Changing color lights on a box ...

Hello all. I know this should be fairly simple, but I can’t quite get it to work right. Here’s the question…

I have 9 boxes. Each box has a red point light as a child of that box. When certain in game conditions are met, the color of the light on a specific box needs to change to green. I know the code for changing the light … here’s the problem I’m having…the boxes are instantiated as GameObjects in one script (PuzzleSetup.cs) and I am trying to change the light from another script. I have already referenced the source script using FindObjectOfType, so that’s not it. Here, look …

public GameObject puzzBox;

void Start () {

puzzle = FindObjectOfType(); // This lets us access the PuzzleSetup.cs variables

switch (this.name) // Check for the size of the bar (i.e. how many “slots” it has) then also check to see if
{ // this bar has a zero on it. If it does, decrease the number of slots by 1.
case “Short0SumBar”:
barCollide = 2;
puzzBox = GameObject(puzzle.sumGO3); <=== This is the problem.
sumMatch = puzzle.short0Sum; <=== This works, so I know I’ve got “puzzle = …” correct.
break;

So, where it says puzzBox = GameObject(puzzle.sumGO3), the sumGO3 is the name of the box in the other script. I want to make sure that’s the object whose light changes later in the code, with this:

puzzBox.GetComponentInChildren().color = Color.green;

Am I on the right track? How can I get this to work? Any help is appreciated.

Please refer to this thread for how to post code nicely on the forums: Using code tags properly

Is that your actual code, or a mock up? I assume a mock up/estimation of what you want.

If you didn’t already say, or I missed it, could you explain under what circumstances these lights will change colour?

@methos5k Sorry about the code blunder, it was my first time ever posting here. I have tried posting questions on the Answers section, but every time I do so, an error message pops up and then I can not get back to the Answers section for several days.

Here is a screen capture of what I am trying to do:

The idea is to take the numbers from the left and drop them in the grid to the right, making the rows in all three directions add up to the number in the glowing box. When the sum is correct (such as the 3 and 0 adding up to 3) the box glow should change to green.

Each of the blue number hexes has a box collider attached. The colored bars running behind the purple hexes will detect the placement of the number, derive the number value, add it to the sum of other numbers on the bar, and determine when the row is full. If it is full and the sum equals the number on the box, click, we change to green.

So in void Start I am assigning the values to the colored bars, such as the amount of number hexes it can hold, if there is a zero on the bar, what the target sum is for that bar (i.e. the number in the box) and the part I’m trying to do but failing at … which GameObject from the other script holds the light to change.

Am I making this too hard? I’m sure this could be done much more elegantly, but I am learning from scratch as I go … I’ve been learning Unity for about 8 months now. Any tips or pointers would be greatly appreciated.

Thanks.

Okay, I get the idea looking at your screenshot.

Is there 1 script for each “bar” that works out that stuff. I’m just checking because I wasn’t sure if it’s 1 per bar or 1 script that does every bar.

One thing/idea that comes to mind, is to simply have 1 template prefab of the game object with a light. The sections will know the sum / number to put on it, and they can instantiate the prefab, keep a reference to it (and therefore also the light), and update the number appropriately.

Let me know if that makes sense or I misunderstood your design a bit :slight_smile:

Here is a screen capture of the scene before we run it.

So you can see that the Sum Boxes are in fact prefabs that I instantiate at runtime. The Sum Box prefab has two children … a text box called SumBoxLabel that gets the number applied to it, and a red point light.

I have a script called PuzzleSetup that initializes all of the answers in the grid and displays the sums. I also have a script called SumCheck, which is where I am having the problem. It is within SumCheck that I wish to change the box’s color, but I cannot seem to reference the game object correctly.

Here is Puzzle Setup. I warn you it is long and ugly.

public class PuzzleSetup : MonoBehaviour
{
    public bool used1 = false;
    public bool used2 = false;
    public bool used3 = false;
    public bool used4 = false;
    public bool used5 = false;
    public bool used6 = false;
    public bool used7 = false;
    public bool used8 = false;
    public bool used9 = false;
    public bool used10 = false;

    public int location1;
    public int location2;
    public int location3;
    public int location4;
    public int location5;
    public int location6;
    public int location7;
    public int location8;
    public int location9;
    public int location10;
    public int dummy1 = 0;  // Holds the random location until we can check it
    public int counter = 0;  // Keeps track of which number we are putting into the location 

    public GameObject HexPrefab;
    public GameObject SumBoxPrefab;

    public int long0Sum;
    public int long60Sum;
    public int long300Sum;
    public int med0Sum;
    public int med60Sum;
    public int med300Sum;
    public int short0Sum;
    public int short60Sum;
    public int short300Sum;


    // Solution initialization
    void Start()
    {

        while (counter < 10)
        {
            counter ++;
            dummy1 = Random.Range(1, 11);  // Select a hex location for the current number
            // Debug.Log("Random number: " + dummy1);

            // Counter represents the numbers 1 through 9, and then the zero as the final number.  The dummy1
            // variable is randomly selecting a location in the pyramid for the current counter number to reside.
            // The variables called used1 thru used10 will indicate that the selected pyramid location is already
            // filled, causing the counter to not increment, effectively selecting a new location for that number.

            switch (dummy1)
            {
                case 1:
                    if (used1 == true)
                    {
                        counter -= 1;
                    }
                    else
                    {
                        used1 = true;

                        GameObject hexGO = (GameObject)Instantiate(
                            HexPrefab,
                            new Vector3(240.918f, 1.48f, 186.21f),
                            Quaternion.Euler(180, 0, 0),
                            this.transform
                            );
                        hexGO.name = "Hex" + dummy1;

                        if (counter == 10)
                        {
                            location1 = 0;
                            hexGO.GetComponentInChildren<TextMesh>().text = "0";
                            hexGO.tag = location1.ToString();

                        }
                        else
                        {
                            location1 = counter;
                            hexGO.tag = counter.ToString();

                        }
                       
                    }
                    break;

                case 2:
                    if (used2 == true)
                    {
                        counter -= 1;
                    }
                    else
                    {
                        used2 = true;

                        GameObject hexGO = (GameObject)Instantiate(
                            HexPrefab,
                            new Vector3(240.088f, 2.96f, 186.21f),
                            Quaternion.Euler(180, 0, 0),
                            this.transform
                            );
                        hexGO.name = "Hex" + dummy1;

                        if (counter == 10)
                        {
                            location2 = 0;
                            hexGO.GetComponentInChildren<TextMesh>().text = "0";
                            hexGO.tag = location2.ToString();

                        }
                        else
                        {
                            location2 = counter;
                            hexGO.tag = counter.ToString();

                        }
                    }
                    break;

                case 3:
                    if (used3 == true)
                    {
                        counter -= 1;
                    }
                    else
                    {
                        used3 = true;

                        GameObject hexGO = (GameObject)Instantiate(
                            HexPrefab,
                            new Vector3(241.8f, 2.96f, 186.21f),
                            Quaternion.Euler(180, 0, 0),
                            this.transform
                            );
                        hexGO.name = "Hex" + dummy1;


                        if (counter == 10)
                        {
                            location3 = 0;
                            hexGO.GetComponentInChildren<TextMesh>().text = "0";
                            hexGO.tag = location3.ToString();

                        }
                        else
                        {
                            location3 = counter;
                            hexGO.tag = counter.ToString();

                        }
                    }
                    break;

                case 4:
                    if (used4 == true)
                    {
                        counter -= 1;
                    }
                    else
                    {
                        used4 = true;

                        GameObject hexGO = (GameObject)Instantiate(
                            HexPrefab,
                            new Vector3(239.078f, 4.42f, 186.21f),
                            Quaternion.Euler(180, 0, 0),
                            this.transform
                            );
                        hexGO.name = "Hex" + dummy1;

                        if (counter == 10)
                        {
                            location4 = 0;
                            hexGO.GetComponentInChildren<TextMesh>().text = "0";
                            hexGO.tag = location4.ToString();

                        }
                        else
                        {
                            location4 = counter;
                            hexGO.tag = counter.ToString();

                        }
                    }
                    break;

                case 5:
                    if (used5 == true)
                    {
                        counter -= 1;
                    }
                    else
                    {
                        used5 = true;

                        GameObject hexGO = (GameObject)Instantiate(
                            HexPrefab,
                            new Vector3(240.918f, 4.42f, 186.21f),
                            Quaternion.Euler(180, 0, 0),
                            this.transform
                            );
                        hexGO.name = "Hex" + dummy1;


                        if (counter == 10)
                        {
                            location5 = 0;
                            hexGO.GetComponentInChildren<TextMesh>().text = "0";
                            hexGO.tag = location5.ToString();

                        }
                        else
                        {
                            location5 = counter;
                            hexGO.tag = counter.ToString();

                        }
                    }
                    break;

                case 6:
                    if (used6 == true)
                    {
                        counter -= 1;
                    }
                    else
                    {
                        used6 = true;

                        GameObject hexGO = (GameObject)Instantiate(
                            HexPrefab,
                            new Vector3(242.758f, 4.42f, 186.21f),
                            Quaternion.Euler(180, 0, 0),
                            this.transform
                            );
                        hexGO.name = "Hex" + dummy1;

                        if (counter == 10)
                        {
                            location6 = 0;
                            hexGO.GetComponentInChildren<TextMesh>().text = "0";
                            hexGO.tag = location6.ToString();

                        }
                        else
                        {
                            location6 = counter;
                            hexGO.tag = counter.ToString();

                        }
                    }
                    break;

                case 7:
                    if (used7 == true)
                    {
                        counter -= 1;
                    }
                    else
                    {
                        used7 = true;

                        GameObject hexGO = (GameObject)Instantiate(
                            HexPrefab,
                            new Vector3(238.376f, 6.02f, 186.21f),
                            Quaternion.Euler(180, 0, 0),
                            this.transform
                            );
                        hexGO.name = "Hex" + dummy1;

                        if (counter == 10)
                        {
                            location7 = 0;
                            hexGO.GetComponentInChildren<TextMesh>().text = "0";
                            hexGO.tag = location7.ToString();

                        }
                        else
                        {
                            location7 = counter;
                            hexGO.tag = counter.ToString();

                        }
                    }
                    break;

                case 8:
                    if (used8 == true)
                    {
                        counter -= 1;
                    }
                    else
                    {
                        used8 = true;

                        GameObject hexGO = (GameObject)Instantiate(
                            HexPrefab,
                            new Vector3(240.088f, 6.02f, 186.21f),
                            Quaternion.Euler(180, 0, 0),
                            this.transform
                            );
                        hexGO.name = "Hex" + dummy1;

                        if (counter == 10)
                        {
                            location8 = 0;
                            hexGO.GetComponentInChildren<TextMesh>().text = "0";
                            hexGO.tag = location8.ToString();

                        }
                        else
                        {
                            location8 = counter;
                            hexGO.tag = counter.ToString();

                        }
                    }
                    break;

                case 9:
                    if (used9 == true)
                    {
                        counter -= 1;
                    }
                    else
                    {
                        used9 = true;

                        GameObject hexGO = (GameObject)Instantiate(
                            HexPrefab,
                            new Vector3(241.8f, 6.02f, 186.21f),
                            Quaternion.Euler(180, 0, 0),
                            this.transform
                            );
                        hexGO.name = "Hex" + dummy1;

                        if (counter == 10)
                        {
                            location9 = 0;
                            hexGO.GetComponentInChildren<TextMesh>().text = "0";
                            hexGO.tag = location9.ToString();

                        }
                        else
                        {
                            location9 = counter;
                            hexGO.tag = counter.ToString();

                        }
                    }
                    break;

                case 10:
                    if (used10 == true)
                    {
                        counter -= 1;
                    }
                    else
                    {
                        used10 = true;

                        GameObject hexGO = (GameObject)Instantiate(
                            HexPrefab,
                            new Vector3(243.512f, 6.02f, 186.21f),
                            Quaternion.Euler(180, 0, 0),
                            this.transform
                            );
                        hexGO.name = "Hex" + dummy1;

                        if (counter == 10)
                        {
                            location10 = 0;
                            hexGO.GetComponentInChildren<TextMesh>().text = "0";
                            hexGO.tag = location10.ToString();

                        }
                        else
                        {
                            location10 = counter;
                            hexGO.tag = counter.ToString();

                        }
                    }
                    break;
            }
        }

        //Debug.Log(location1 + " is in Location 1");
        //Debug.Log(location2 + " is in Location 2");
        //Debug.Log(location3 + " is in Location 3");
        //Debug.Log(location4 + " is in Location 4");
        //Debug.Log(location5 + " is in Location 5");
        //Debug.Log(location6 + " is in Location 6");
        //Debug.Log(location7 + " is in Location 7");
        //Debug.Log(location8 + " is in Location 8");
        //Debug.Log(location9 + " is in Location 9");
        //Debug.Log(location10 + " is in Location 10");

        long0Sum = location7 + location8 + location9 + location10;

        GameObject sumGO1 = (GameObject)Instantiate(
            SumBoxPrefab,
            new Vector3(237.22f, 7.07f, 186.05f),
            Quaternion.Euler(180, 180, 0),
            this.transform
            );
        sumGO1.name = "long0Sum";
        sumGO1.tag = long0Sum.ToString();
        sumGO1.GetComponentInChildren<TextMesh>().text = long0Sum.ToString();
       

        med0Sum = location4 + location5 + location6;

        GameObject sumGO2 = (GameObject)Instantiate(
            SumBoxPrefab,
            new Vector3(237.97f, 5.6f, 186.05f),
            Quaternion.Euler(180, 180, 0),
            this.transform
            );
        sumGO2.name = "med0Sum";
        sumGO2.tag = med0Sum.ToString();
        sumGO2.GetComponentInChildren<TextMesh>().text = med0Sum.ToString();

        short0Sum = location2 + location3;

        GameObject sumGO3 = (GameObject)Instantiate(
            SumBoxPrefab,
            new Vector3(238.72f, 4.13f, 186.05f),
            Quaternion.Euler(180, 180, 0),
            this.transform
            );
        sumGO3.name = "short0Sum";
        sumGO3.tag = short0Sum.ToString();
        sumGO3.GetComponentInChildren<TextMesh>().text = short0Sum.ToString();

        long60Sum = location1 + location3 + location6 + location10;

        GameObject sumGO4 = (GameObject)Instantiate(
            SumBoxPrefab,
            new Vector3(245.80f, 9.03f, 186.05f),
            Quaternion.Euler(180, 180, 60),
            this.transform
            );
        sumGO4.name = "long60Sum";
        sumGO4.tag = long60Sum.ToString();
        sumGO4.GetComponentInChildren<TextMesh>().text = long60Sum.ToString();

        med60Sum = location2 + location5 + location9;

        GameObject sumGO5 = (GameObject)Instantiate(
            SumBoxPrefab,
            new Vector3(244.05f, 9.03f, 186.05f),
            Quaternion.Euler(180, 180, 60),
            this.transform
            );
        sumGO5.name = "med60Sum";
        sumGO5.tag = med60Sum.ToString();
        sumGO5.GetComponentInChildren<TextMesh>().text = med60Sum.ToString();

        short60Sum = location4 + location8;

        GameObject sumGO6 = (GameObject)Instantiate(
            SumBoxPrefab,
            new Vector3(242.30f, 9.03f, 186.05f),
            Quaternion.Euler(180, 180, 60),
            this.transform
            );
        sumGO6.name = "short60Sum";
        sumGO6.tag = short60Sum.ToString();
        sumGO6.GetComponentInChildren<TextMesh>().text = short60Sum.ToString();

        long300Sum = location1 + location2 + location4 + location7;

        GameObject sumGO7 = (GameObject)Instantiate(
            SumBoxPrefab,
            new Vector3(242.96f, 1.0f, 186.05f),
            Quaternion.Euler(180, 180, 300),
            this.transform
            );
        sumGO7.name = "long300Sum";
        sumGO7.tag = long300Sum.ToString();
        sumGO7.GetComponentInChildren<TextMesh>().text = long300Sum.ToString();

        med300Sum = location3 + location5 + location8;

        GameObject sumGO8 = (GameObject)Instantiate(
            SumBoxPrefab,
            new Vector3(243.95f, 2.55f, 186.05f),
            Quaternion.Euler(180, 180, 300),
            this.transform
            );
        sumGO8.name = "med300Sum";
        sumGO8.tag = med300Sum.ToString();
        sumGO8.GetComponentInChildren<TextMesh>().text = med300Sum.ToString();

        short300Sum = location6 + location9;

        GameObject sumGO9 = (GameObject)Instantiate(
            SumBoxPrefab,
            new Vector3(244.92f, 4.1f, 186.05f),
            Quaternion.Euler(180, 180, 300),
            this.transform
            );
        sumGO9.name = "short300Sum";
        sumGO9.tag = short300Sum.ToString();
        sumGO9.GetComponentInChildren<TextMesh>().text = short300Sum.ToString();

    }

}

When you see me name something like short60Sum, that is the sum box on the short bar rotated at 60 degrees.

Sorry, just realized that I didn’t fully answer your question. SumCheck will be a component on each individual bar, so they will each check their own selves for the number of hexes that collide with it. Is that the problem? Do I only have to check the sum box that is colliding with it? Perhaps by checking for a tag? I feel like I’m on the verge of a revelation here… am I close?

Okay, so you don’t really use arrays or lists much :slight_smile:

Okay, your most recent post updated with some helpful information. What I was thinking was why not just pass the reference to the game object with the light to the SumCheck script when you create it?

That would allow it to have direct access when it gets the right sum on its line.

Your code is a bit long to look over, but can you get the SumCheck script from the Setup script? (for each section)?

Just a suggestion for future posts: my humble experience show that people carry very little on forums when you dump huge walls of code and write vague explanations of the problems you have. Narrow down the problem, explain it clearly (like if you are talking to your grandma, and this is not a joke), post only the specific part of the code and you will get much more help.

It’s true, this question sounds like this:

How do I pass a reference from 1 script to another, when the object is instantiated at runtime (and so is the second script). I think that’s what’s been said.

@cubrman - A very good tip. You might notice that I tried to do just that with my very first post … I just wasn’t explaining myself very well. Methos5k was trying to help, so I hit him specifically with my ginormous wall o’ code. In this instance, unfortunately, I am the grandma.

@methos5k - I don’t have a firm grasp of the correct usage of lists, it’s true. I hadn’t encountered arrays in C# yet when I started this project, and I wanted to get it working before I tried to rewrite anything. Also, I guess I don’t know when it’s okay to pass a reference through. I assume you mean by putting the reference in parenthesis after the method is called?

If you don’t mind … what might this look like in this case?

Your code will work with or without arrays/lists. I just mentioned that, as I would do anytime I see “item1, item2, item3, item4, etc…” :slight_smile:

Okay, so in the super simplest terms, it might look like this:
Script 1 does the setup. It builds what you need, including the “bars” that have the Script #2. Let me know if this is correct, so far.

So, when setting this up, from Script 1, get the component (script) of each bar, and set a variable on them that references the light (box).

Imagine, in a super simple example (not directly about your game / scene).
I have a script in the scene with a reference to some cube.

I instantiate a new cube, from this first script. My new cube has a different script on it.

On the new cube’s script, I want to have access to the cube in the scene. I can’t connect it on the prefab, because that doesn’t work. However, what I can do is use GetComponent on the new game object I’ve spawned (from the first script), and set a variable on it (passing them the reference it has to the cube in the scene).

@methos5k - Let me see if I have this straight, and thank you for your time.

Each sum bar holds the second script. The first script instantiates and uniquely names each sum box. The second script links the first script’s objects and variables using :

private PuzzleSetup puzzle;

and

puzzle = FindObjectOfType<PuzzleSetup>();

Now, in the Start() I use a switch keyed to the name of the bar the script is attached to, and in the case I reference the box that coincides with this bar. To wit:

switch (this.name)
{
case "Short0SumBar":
                puzzBox = GameObject.Find("short0Sum");
                break;

And finally, later in the code, we change the light attached to the box named short0Sum which is assigned to puzzBox like so:

puzzBox.GetComponentInChildren<Light>().color = Color.green;

Will this work?

Hmm. That’s actually not what I was thinking.

I was thinking that when you build your puzzle, several pieces have the script (you’ve told me), and that script wants to know how to access the light.

So, inside the puzzle setup script, get that Sum Script (whatever it’s called) from the proper game object and tell it which light is its (light).

I wish I could convey this message more clearly, because I feel like we’re getting confused :wink:

@methos5k - I agree, confusion abounds. I tried mine, attached the SumCheck.cs (the second script) to each bar, and it’s throwing a NullReference error in the color change line. (puzzBox …color = Color.green; that one).

So let me try to understand again what you are saying. After the sum box with its light is instantiated inside of PuzzleSetup.cs, I do something like:

Public Light sumLight;
Light SumLight = sumGO1.GetComponentInChildren<Light>();

and maybe I name the light with …

sumLight.name = "long0SumLight";

And then how does SumCheck.cs know which sumLight is the right one?

If I just put:

 puzzle.sumLight.color = Color.green;

then which box will change color? Don’t I need to indicate which box we have?

Okay so I ran with this, and I was told that PuzzleSetup needed a light assigned, so I went into the inspector and dragged the point light from the sum box prefab into the slot. Voila! All my boxes start out green! Ugh! But I know we’re close… what am I missing?