How do I activate game objects in array in timed loop?

I have a scene with an array containing 10 objects. I want to loop through each game object, activate it for 20 seconds, then deactivate it and then do it for the next object in the array. I want it to basically keep looping through the game objects as long as a bool is true.

I’ve been googling a lot and scouring through answers. I’m pretty sure that I’ll want to use a coroutine, but not quite sure how I can pull this off.

Logic-wise, basically I want to do this.

-While attractorMode=true

  • set gameobject1 active
  • wait 20 seconds
  • set gameobject1 to inactive
  • set gameobject2 active
  • wait 20 seconds
  • set gameobject2 to inactive

I want repeat for all 10 objects and then restart back with gameobject1 once all 10 have finished.

Thanks for any tips, code or just pointing me in the right direction.

From your description, it’s clear that you must be cautious about invoking your coroutine, such that it is only running one instance at a time.

When your bool becomes false, do you want the next pending transition to occur, or not occur? The following code will execute the pending change, even once you set attractorMode to false. This can be corrected if it’s not what you want, but it’s up to you to figure out how. :smiley:

Hopefully this’ll give you some insight into how coroutines work. Your request is just potentially-confusing enough to warrant a demonstration script, but don’t expect free scripts too often. :wink:

bool attractorMode, isRunning;
int currentIndex;

void Update() {
  // only invoke if the coroutine isn't already running
  if (attractorMode && !isRunning) StartCoroutine( Cycle() );
}

IEnumerator Cycle() {
  // these lines execute by the end of the frame in which Cycle() was invoked
  isRunning = true;
  objects[currentIndex].SetActive(true);
  yield return new WaitForSeconds(20);

  // execution will not return to the next statement until 20 seconds later    

  objects[currentIndex].SetActive(false); 

  // increment the index and ensure it loops around at the end
  currentIndex++;
  if (currentIndex >= objects.Length) currentIndex = 0;

  isRunning = false;
}