- Home /
toggle gameObjects with a keyPress
So i have four public gameObjects, say, ghost1, ...2, ...3, ...4 and a private gameObject, say, tempGO in my script that is attached to an empty that is the parent of 4 objects that are the candidates for the above said public gameObjects. So when the game starts, ghost1 must be active while the others are not. In the Update method, i am using a for loop to set the next gameObject that is line to be active while the others go inactive.
public class playerSwitching : MonoBehaviour {
private string characterName;
private GameObject tempGO;
//public GameObject ghost1;
//public GameObject ghost2;
//public GameObject ghost3;
//public GameObject ghost4;
public int characterNumber = 1;
// Use this for initialization
void Start () {
for (int i = 0; i < 5; i++)
{
if (i == 1)
{
/*characterName = "ghost" + i;
gameObjRend = GameObject.Find(characterName);
gameObjRend.SetActive(true);*/
}
else
{
/*characterName = "ghost" + i;
gameObjRend = GameObject.Find(characterName);
gameObjRend.SetActive(false);*/
}
}
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Space))
{
if (characterNumber < 4)
{
characterNumber++;
}
else
{
characterNumber = 1;
}
for(int i = 0; i < 5; i++)
{
if (i != characterNumber)
{
/*characterName = "ghost" + i;
gameObjRend = GameObject.Find(characterName);
gameObjRend.SetActive(false);*/
}
else
{
/*characterName = "ghost" + characterNumber;
gameObjRend = GameObject.Find(characterName);
gameObjRend.SetActive(true);*/
}
}
}
}
}
The technique I've implemented here doesn't use the public gameObjects. The gameObject that comes in line after the current and active one should be activated while the others are deactivated; in the case where the 4th one is active, the first should be activated. And I read somewhere that Find method is not advised and is also very slow. So can anyone help me here?
Answer by DiegoSLTS · Apr 19, 2019 at 04:32 PM
You souldn't call Find in an Update method, that is what people usually mean when saying you should avoid using Find. It's OK to use Find every now and then, using it on Start or Awake methods is not bad.
Instead of using 4 different GameObject members I'd use one GameObject[], it's easier to work with it within for loops.
This should be OK for your use case:
public GameObject[] ghosts;
public int characterIndex = 0;
void Start () {
ghosts = new GameObject[4];
for (int i = 0; i < 4; i++) {
ghosts[i] = GameObject.Find("ghost" + (i+1));
ghosts[i].SetActive(i == 0);
}
}
void Update () {
if (Input.GetKeyDown(KeyCode.Space)) {
if (characterIndex < 3) {
characterIndex++;
} else {
characterIndex = 0;
}
for(int i = 0; i < 4; i++) {
ghosts[i].SetActive(i == characterIndex);
}
}
}
Important: note the for loop goes from 0 to 3 (i < 4). Arrays are zero-indexed so the first element is 0, not 1. Considering this, it's better to keep track of the index (0 through 3) instead of the ghost number (1 through 4) so the code is cleaner. Since the ghosts names are not zero-based, the Find line adds 1 to the i value so for the first element (i == 0) the first ghost ("ghost1") is found.
Also, if tempGO is the parent of the ghost objects, you could replace GameObject.Find (which searchs in the whole hierarchy) with tempGO.transform.Find (which searches only under the tempGO object) and you'll have less expensive Find calls. And if tempGO only has the ghost objects and you make sure they're in the right order, you can avoid the Find completelly and replace the Find line with something like:
ghosts[i] = tempGO.transform.GetChild(i);
Note that in this case you don't use the names for anything.