Sequential GameObject Activation

This seems like the simplest thing but I can’t figure it out for the life of me.

I have 400 unique GameObjects that I would like to Activate at different times during an animation. Each GameObject needs to be at very exact location and rotation so I believe .SetActive would be better than trying to Instantiate each one individually. It would also be nice to avoid writing a 400 item Hashtable or Dictionary.


I am simply trying to create a script that will:

  1. Disable Current GameObject
  2. Find next GameObject
  3. Enable next GameObject

Here is my current attempt at naming each GameObject a number 1-400 and converting a variable back-and-forth between a String and an Int:

private var currentObject : int = 1;

function NextFrame () {

	currentObject.ToString();
	
	GameObject.Find("currentObject").SetActive (false);
	
	int.Parse(currentObject) += 1;
	
	GameObject.Find("currentObject").SetActive (true);
}

Try this:

var objectHolder : GameObject;
private var objects : Transform[];
private var current : int;

function Start() {
    objects = objectHolder.GetComponentsInChildren(Transform) as Transform[];
    for (var t : Transform in objects) {
        t.gameObject.SetActive(false);
    }
    current = 0;
    objects[current].gameObject.SetActive(true);
}

function NextFrame() {
    objects[current].gameObject.SetActive(false);
    current = (current + 1) % objects.Length;
    objects[current].gameObject.SetActive(true);
}

Notes:

  1. Put your 400 objects under a single game object in the hierarchy, and assign this object to the objectHolder property of the script.
  2. The Start() function makes an array of all of the objects under the objectHolder, and activates only the first one.
  3. The NextFrame() function just cycles through the array.
  4. You should check bounds and check for null, but I omitted that for clarity.
  5. Untested code, but it should get the idea across. [Edit: Still untested, but should probably work now. :-)]

Here’s a modified version of your method. First, the gameobjects tagged ‘Animate’ are stored in a list and then sorted by name. Then each tick, it does basically the same as your script, but uses the array to look the gameobjects up instead of the .Find method.

import System.Linq;

private var gameObjectList : GameObject[];
private var currentObject : int = -1;
 
function Start () {
    gameObjectList = GameObject.FindGameObjectsWithTag("Animate").OrderBy(function(g){g.SetActive(false);return g.name;}).ToArray();
}
 
function NextFrame () {
    gameObjectList[(currentObject++%gameObjectList.Length+gameObjectList.Length)%gameObjectList.Length].SetActive(false);
    gameObjectList[currentObject].SetActive(true);
}

–David–