Madame Green Pea
Madame Green Pea

Reputation: 187

How to destroy and spawn different GameObjects in specified seconds using coroutine?

I am working on an educational kids game. Teaching materials should horizontally scroll one by one, together with the related audio files. For example, if the cat image is on the screen, then the cat sound plays.

I am trying to use coroutines. But GameObjects aren't destroyed individually. All of the previously spawned GameObjects are waiting for the new spawning GameObjects and they are being destroyed at once after all GameObject spawns.

[SerializeField] private GameObject[] sceneObjects;
[SerializeField] private int objectSlideSpeed;
[SerializeField] private int timer;
[SerializeField] private float targetLocation;

void Update()
{
    StartCoroutine(SlideLeft());
}

IEnumerator SlideLeft()
{
    for (int i = 0; i < sceneObjects.Length; i++)
    {
        while(sceneObjects[i].transform.position.x > targetLocation)
        {
            sceneObjects[i].transform.Translate(objectSlideSpeed * Time.deltaTime * Vector3.left);
            yield return new WaitForSeconds(timer);

            if (sceneObjects[i].transform.position.x < targetLocation)
            {
                StopSlide(); // objectSlideSpeed = 0;
                Destroy(sceneObjects[i]);
            }
        }
    }
}

Expected

Current Situation

preview

Upvotes: 1

Views: 399

Answers (1)

Menyus777
Menyus777

Reputation: 7007

[SerializeField] private GameObject[] sceneObjects;
[SerializeField] private int objectSlideSpeed;
[SerializeField] private int timer;
[SerializeField] private float targetLocation;

// When the scene loads, you dont want update or else the coroutine will be called every frame
void Start()
{
    StartCoroutine(SlideLeft());
}

IEnumerator SlideLeft()
{
    for (int i = 0; i < sceneObjects.Length; i++)
    {
        // [Here], on while we check the conidtion and if it is not true we dont step into it
        while(sceneObjects[i].transform.position.x > targetLocation)
        {
            sceneObjects[i].transform.Translate(objectSlideSpeed * Time.deltaTime * Vector3.left);
            // Why you need a timer, if your goal is to start a gameobject when the other one arrived,
            // at its destination? O.o
            // yield return new WaitForSeconds(timer);

            yield return null; // After this yield execution will continue on the [Here] Tag
        }
        StopSlide();
        Destroy(sceneObjects[i]);
    }
}

There is some things that i do not understand, in your expected behavior, but write a comment if i misunderstood something.

And the reason why it seems like it works is because you called them in update, but you like created a million coroutines and hundred of thousands were in paused execution.

Upvotes: 1

Related Questions