0
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

Daniel Lip
  • 1,747
  • 3
  • 34
  • 75

1 Answers1

1

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.

Philipp
  • 119,250
  • 27
  • 256
  • 336
  • 1
    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. – DMGregory Nov 12 '21 at 14:48
  • I'm getting error on the default Control cannot fall out of switch from final case label ('default:') – Daniel Lip Nov 12 '21 at 14:52
  • @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. – Philipp Nov 12 '21 at 14:53
  • @user1741587 fixed. – Philipp Nov 12 '21 at 14:54
  • @Philipp another problem is the "squad" objects are empty gameobjects without any renderer material I need to loop with the color on the inner loop of the squad members and then somehow to color each squad member depending on the squad he belong to. – Daniel Lip Nov 12 '21 at 14:54
  • 1
    @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). – Philipp Nov 12 '21 at 14:58
  • @Philipp I added a screenshot to my question to show the hierarhcy. the squad objects are just empty gameobjects and the squad members are child of each one. – Daniel Lip Nov 12 '21 at 14:58
  • @user1741587 The ColorSquad method as I wrote it here should actually work on any gameObject with a Renderer with a material with a _Color property. So you could use this as-is if you moved the call to the innerLoop and passed go instead of newSquad. – Philipp Nov 12 '21 at 15:02
  • @Philipp if I remove the default still the last squads are in white. how can I make that it will keep color all the squads no matter how many squads there are just to start to color over again from the first color ? everything is working fine I just wonder what if I want all the squads to be colored and not in white the last ones. – Daniel Lip Nov 12 '21 at 15:37
  • 1
    @user1741587 In that case you would use the remainder-operator to pick the color index. squadNumber % numberOfColors. – Philipp Nov 12 '21 at 15:58
  • Working thanks. – Daniel Lip Nov 12 '21 at 22:46