0
\$\begingroup\$
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SquadsGenerator : MonoBehaviour
{
    public GameObject squadPrefab;
    public int numberOfSquads;
    public int numberOfMembersInsquad;

    private GameObject squadsParent;

    private void Start()
    {
        squadsParent = GameObject.Find("Squads");
        GenerateSquads(numberOfSquads, numberOfMembersInsquad, squadPrefab);
    }

    // Update is called once per frame
    void Update()
    {

    }

    public void GenerateSquads(int squadsCount,
        int numberOfMembers,
        GameObject squadMemberPrefab)
    {
        for (int i = 0; i < squadsCount; i++)
        {
            GameObject newSquad = new GameObject();
            newSquad.name = "Squad " + i;
            newSquad.tag = "Squad";
            newSquad.transform.parent = squadsParent.transform;

            ColorSquads(newSquad);

            for (int x = 0; x < numberOfMembers; x++)
            {
                var go = Instantiate(squadMemberPrefab);
                go.name = "Member " + x;
                go.tag = "Squad Member";
                go.transform.parent = newSquad.transform;
            }
        }
    }

    private void ColorSquads(GameObject squad)
    {
        //Fetch the Renderer from the GameObject
        Renderer rend = squad.GetComponent<Renderer>();

        //Set the main Color of the Material to green
        rend.material.shader = Shader.Find("_Color");
        rend.material.SetColor("_Color", Color.green);

        //Find the Specular shader and change its Color to red
        rend.material.shader = Shader.Find("Specular");
        rend.material.SetColor("_SpecColor", Color.red);
    }
}

But now it will color all the squads in green.

I want that it will color the first squad for example in green the next squad in red the next in green and so on. green,red,green,red....

To extend the method ColorSquads to get two colors for example Color 1, Color 2 and this will set the colors switch to color each squad once in Color 1 once in Color 2.

Screenshot of the hierarchy each Squad is empty gameobject and the squad members are child of each squad.

hierarchy of the squads

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

First I would rename the method ColorSquads to ColorSquad. After all, it changes the color of one squad, not of multiple. Then I would add a second parameter color so it takes the color which it is supposed to use for this particular squad:

private void ColorSquad(GameObject squad, Color color)
{
    Renderer rend = squad.GetComponent<Renderer>();
    rend.material.SetColor("_Color", color);
}

But now you of course need to state which color you want to use for each squad within the for-loop. And considering that your code allows any number of squads, you need to decide here which squad-number should get which color. A simple way to do that is via a switch/case:

switch(i) {
   case 0: ColorSquad(newSquad, Color.green); break;
   case 1: ColorSquad(newSquad, Color.red); break;
   case 2: ColorSquad(newSquad, Color.blue); break;
   case 3: ColorSquad(newSquad, Color.yellow); break;
   case 4: ColorSquad(newSquad, Color.cyan); break;
   case 5: ColorSquad(newSquad, Color.magenta); break;
   default: ColorSquad(newSquad, Color.white); break;
}

This will color the first 6 squads with 6 different colors and then use white for any further squads. If you want to support more squads with more colors, then modify this code accordingly.

Another option would be to make those colors configurable in the inspector of this component. Add this variable to the class:

public Color[] squadColors;

Then in the for-loop:

if (i < squadColors.Length) {
    // pick the color from the list
    ColorSquad(newSquad, squadColors[i]);
} else {
    // default color when you run out of colors
    ColorSquad(newSquad, Color.white); 
}

Now you can set the squad colors in the inspector.


By the way: Using red and green for the two most used squads might not be the best decision, because of red/green color blindness. It affects about 10% of all genetically male people, making it the most common form of color-blindness. But that's a different question.

\$\endgroup\$
11
  • 1
    \$\begingroup\$ One thing to watch for here is this method creates a new copy of the material when you access it with rend.material. That copy won't get garbage collected automatically except during a scene load, so you might want to add a little book-keeping to keep track of when it's no longer needed and manually Destroy() it. \$\endgroup\$
    – DMGregory
    Commented Nov 12, 2021 at 14:48
  • \$\begingroup\$ I'm getting error on the default Control cannot fall out of switch from final case label ('default:') \$\endgroup\$
    – Daniel Lip
    Commented Nov 12, 2021 at 14:52
  • \$\begingroup\$ @DMGregory What I would actually recommend is to either create a separate material asset for each squad and assign those or to use MaterialPropertyBlocks. But I didn't want to deviate more than necessary from OPs original design. \$\endgroup\$
    – Philipp
    Commented Nov 12, 2021 at 14:53
  • 1
    \$\begingroup\$ @user1741587 That requirement wasn't in your original question. But when the members are children of the squad object, then you can loop through them with foreach (Transform squadMember in squad.transform). \$\endgroup\$
    – Philipp
    Commented Nov 12, 2021 at 14:58
  • 1
    \$\begingroup\$ @user1741587 In that case you would use the remainder-operator to pick the color index. squadNumber % numberOfColors. \$\endgroup\$
    – Philipp
    Commented Nov 12, 2021 at 15:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .