- Home /
Help with Putting GameObjects into a list.
HI, and Thank you for your help. I made a Maze Generator, and I want to assign a material to all of the walls in the maze. I am doing this by creating a list with all of the walls in the game, Colors. I achieve this by finding all game objects with the name Wall(Clone), because they are all instantiated. I Then Add a script which changes the material to my desired material (in FloorColor). I then change the name of the wall from "WallClone" to "TempWall" to show that the wall has been affected. I then set the Temp wall Game object to Null, and repeat the scenario until the number of walls in Color is = to the total walls in the game.
void ColorWalls()
{
Debug.Log(totalwallcolor);
while (Colors.Count < totalwallcolor)
{
GameObject Tempwall = GameObject.Find("Wall(Clone)");
Tempwall.AddComponent<FloorColor>();
Tempwall.name = ("tempwall");
Tempwall = null;
if(Colors.Count == totalwallcolor)
{
Debug.Log(Colors.Count + "amount in colors");
}
Colors.Add(Tempwall);
}
}
My issue is that the Code Debugs the correct amount of walls in the Color list, Color = Totalwalls, but in the game Heiarchy about 40% of my walls are still WallClone and without the correct script! What Am I doing Wrong? Also, the number of walls not affected changes every time.
Answer by Martin_Gonzalez · Mar 27, 2018 at 05:56 PM
You can use a List<T>
, being T the object type you want, can be GameObject or Wall or whatever.
List is dynamic so you can do something like this:
List<GameObject> myList = new List<GameObject>();
void ColorWalls(){
var maxQuantity = 10;
Debug.Log("Start Finding Walls!");
for (int i = 0; i < maxQuantity; i++)
{
GameObject Tempwall = GameObject.Find("Wall(Clone)");
Tempwall.AddComponent<FloorColor>();
Tempwall.name = ("tempwall");
myList.Add(Tempwall);
}
Debug.Log("Finished!");
}
However calling GameObject.Find("Wall(Clone)"
will not warranty that will find every Wall(Clone) in the scene. Perhaps it repeats some of them.
You can tag gameObjects and find all gameObjects with the desire tag.
I tried your method, and I still get the same error, about 20-40% of the walls are skipped for some reason.
This is because i told you
You can tag gameObjects and find all gameObjects with the desire tag. Try this. -Go to your walls in the scene and set a tag "Wall" to all of them (if you don't know how to tag them follow this video: https://www.youtube.com/watch?v=0XgOJ7ioSuA)However calling GameObject.Find("Wall(Clone)" will not warranty that will find every Wall(Clone) in the scene. Perhaps it repeats some of them.
After you set the same tag to all of your walls use this script.
Thank you for the follow up FYI, Here is the issue, I dont have the walls in the scene before I run the scene, so I have to add them with scripts after the fact. Here is my code now.
void ColorWalls()
{
Debug.Log(totalwallcolor);
for (int i = 0; i<totalwallcolor; i++)
{
GameObject Tempwall = GameObject.Find("Wall(Clone)");
Tempwall.gameObject.tag = ("wall");
Tempwall.GetComponent<Renderer>().material = wallmat;
Tempwall.name = ("tempwall");
Colors.Add(Tempwall);
}
Debug.Log("finished");
}
Only about 80% of the walls are tagged =/
Do you have a prefab and instantiate them?
Let me tell you the problem about that 80%
GameObject.Find("Wall(Clone)) will try to find a gameObject with that name. In the next iteration it will find again a gameObject with that name BUT CAN BE THE ONE YOU FOUND BEFOR$$anonymous$$
So you need to tag them. And search them via GameObject.FindGameObjectsWithTag("Wall")
Answer by DarkFang100 · Mar 27, 2018 at 05:10 PM
You should probably try doing something like public GameObject[] objects; (this is an array) or public List objects (this one I have less experience with so I don't know too much of the syntax). Then, unfortunately you would have to add in the walls manually into the array, but you could also do it in the inspector. Then, in the update function, do a for loop which will go through each of the different walls, noting that you will have to make it loop through until one less then the final wall. This is because with arrays, the first item in the array is index[0]. Then, inside of the for loop, you put the code you had before, except you take out the Color.Add(Tempwall);, because this will add walls to the array of walls that you already have. It should look something like this:
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class ScriptForUnityAnswers : MonoBehaviour {
public GameObject[] objects; //Here you go into the inspector and add in the walls manually
void Start () {
}
void Update ()
{
ColorWalls ();
}
void ColorWalls () {
int i;
for (i = 0; i < objects [i]; i++)
{
GameObject Tempwall = GameObject.Find ("Wall(Clone)");
Tempwall.AddComponent<FloorColor> ();
Tempwall.name = ("tempwall");
Tempwall = null;
if (Colors.Count == totalwallcolor)
{
Debug.Log (Colors.Count + "amount in colors");
}
}
}
//Don't forget your Colors void
}
I would do that, however, I don't know how many walls will be generated, because its random, so I cant add them to an array, you cant add something that doesn't exist yet. That's why I have Color.Add, it adds the GameObject to the list.
@quadack oh then you could add into the array a Random.Range variable (set somewhere else) to compensate for the randomness. $$anonymous$$ake note that you would need to use that variable to manipulate the amount of walls you have in the scene, too.