- Home /
How do I create a variable for each GameObject that I added to an array by using a loop?
I have this and I would like to be able to check to see if all of the variables in each object is the same. Is myColor = 1 (or any other number) for each of them. If they are, then I want to do something. The problem is I don't know if it is making a variable for each one as it is. Nor do I know how to check it if it was.
It currently prints out each of the objects myColor int properly, but is there another loop that I would need to run to have it be visible for me to use? And once I get each of the gameObjects their own variable, would some type of loop be best to check if all of them are the same?
Currently it looks like whatColorAmI will be rewritten with a new value as the loop goes on, which is not what I need.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Main_Script : MonoBehaviour {
public GameObject[] pieces;
// Use this for initialization
void Start () {
pieces = GameObject.FindGameObjectsWithTag("Piece");
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown (KeyCode.E))
RecallColors ();
}
void RecallColors ()
{
foreach (GameObject piece in pieces)
{
int whatColorAmI = piece.GetComponent<PieceScript>().myColor;
Debug.Log (whatColorAmI);
}
}
}
Answer by sleepandpancakes · Apr 16, 2017 at 09:09 PM
PieceScript[] pieces;
void Start()
{
pieces = GameObject.FindObjectsOfType<PieceScript>();
}
bool AreAllColorsSame()
{
int firstColor = pieces[0].myColor;
foreach (PieceScript piece in pieces)
{
if (piece.myColor != firstColor)
return false;
}
return true;
}
I didn't realize you had posted as well. I posted the finished code down below and it makes sure to account for all the occupants of my array. I do wish that I had seen it first as it would have made the process a little faster. ^_^ I do appreciate it though.
One question though. Why do you use FindObjectsOfType rather than finding them by tag? I may change my method to a bool. And that one wouldn't update as the "pieces" change colors correct?
I use FindObjectsOfType at the beginning so that pieces
refers directly to the PiecesScript objects ins$$anonymous$$d of the GameObjects that have those components. So when we use PieceScript[] pieces
ins$$anonymous$$d of GameObject[] pieces
, we don't have to keep using GetComponent() each time we want to access the myColor
field. So it's more concise and performant.
I recommend changing the method to a bool as it makes your code more functionally oriented. Your goal was to check if something is true or not, so it makes sense to define your method as a bool.
As long as you keep the same array of PieceScript objects, the method should work fine even if you change the colors of the pieces because it accesses the color values each time you run the method. In fact it should do basically the same thing as your method, it just takes less code.
That makes sense. And I'm thinking that I could use the logic from this to help the performance of the other game that I was working on. I know it's a bad way to do it and I knew it was when I did it. I just didn't know of a good way to do it.
The other game worked by having 300 or so game objects that would broadcast up into a center game object then it broadcast back to them. All I wanted it to do was change the levels for each one but I wanted to make sure none of them somehow got into the wrong level. It worked great on my computer then the frame rate halved when I put it on my phone. This seems like the perfect way to fix it although since the game was almost done, it will take a lot of backtracking. Or it might not because the broadcast lines of code only took up at most 3 lines per script that needed it. Do you think this would drastically improve performance?
Answer by hexagonius · Apr 16, 2017 at 09:07 PM
You have the choice between while, for and foreach. While would be used for an unknown interation count, but you want to iterate all pieces, so you know the count. A for loop is used if you want anything else than reading something. In your case, you're just reading values, not altering order or anything, so foreach is the perfect pic.
If you want to check if all the values are the same, you could save myColor from the first item before the loop. Within the loop, continue the loop if the iterated item is that first one (`if (piece == pieces[0]) continue;`)
When you now compare each iterated item with the myColor you saved before the loop, nothing gets overridden and you know when it's different from the first. Of course this excludes the first from being different from the other, so you cannot react to that, but what the value is you want to compare with, only you know.
That might work. I will test that here in a few $$anonymous$$utes, but the idea sounds like what I am looking for. I will post once I am finished.
It took me a bit to figure it out. $$anonymous$$ainly the problem with continue as it would skip the rest of the code even after the loop was done. But now it runs really well. Thank you for the help.
void RecallColors ()
{
int whatColorAmI = pieces[0].GetComponent<PieceScript>().myColor;
foreach (GameObject piece in pieces) {
int colorToCompare = piece.GetComponent<PieceScript> ().myColor;
if (colorToCompare == whatColorAmI){
color$$anonymous$$atchCount++;
if (color$$anonymous$$atchCount != pieces.Length)
continue;
}
if (color$$anonymous$$atchCount == pieces.Length) {
doAllColors$$anonymous$$atch = true;
Debug.Log (doAllColors$$anonymous$$atch);
} else {
Debug.Log (doAllColors$$anonymous$$atch);
color$$anonymous$$atchCount = 0;
}
}
}