R
R
Roman2019-02-21 23:10:10
C++ / C#
Roman, 2019-02-21 23:10:10

Why is this code not working?

Hello!
There is this piece of code:

void ChangePos(List<Vector2> pointss, GameObject temp)
    {
        for (int i=0; i<pointss.Count; i++)
        {
            StartCoroutine(ExecuteAfterTime());
            temp.transform.position = pointss[i];
        }
    }

    IEnumerator ExecuteAfterTime()
    {
        yield return new WaitForSeconds(1);
    }

The point is that I'm dragging the GameObject along some kind of trajectory. Transition between coordinates - 1 second. But on checking, the object is immediately at the end, and does not "pass" along the path. What is the problem?

Answer the question

In order to leave comments, you need to log in

5 answer(s)
D
Denis Gaydak, 2019-02-22
@ananas_roma

I'll try to explain it in a simpler way or something))
So you launched the coroutine in the line
StartCoroutine(ExecuteAfterTime());
it will immediately start executing it, and will execute all calls inside the coroutine until it hits some kind of "wait", in your case
yield return new WaitForSeconds(1);
stumbled -> immediately returned to the main thread and continued to execute
temp.transform.position = pointss[i]; and then the cycle.
and conditionally after "wait", it will continue to execute the coroutine (again from the main thread, looking into it)
(in reality, of course, there is a little differently, but it will do for understanding)

void ChangePos(List<Vector2> pointss, GameObject temp)
    {
        for (int i=0; i<pointss.Count; i++)
        {
            StartCoroutine(ExecuteAfterTime());
           Debug.Log("from FOR _"+i.ToString());
            temp.transform.position = pointss[i];
        }
    }

    IEnumerator ExecuteAfterTime()
    {
        yield return new WaitForSeconds(1);
       Debug.Log("Arter 1 second");
    }

try this code and you will understand when and what is called.
and that, in general, it was correctly explained to you that if you want to stretch the cycle in time, then push it all into a coroutine.

G
GavriKos, 2019-02-21
@GavriKos

Because your code is wrong. It is necessary to shove everything into a coroutine.

C
CHolfield, 2019-02-21
@CHolfield

Because the docs say:
A StartCoroutine function terminates immediately, however, the Coroutine it creates runs as expected.
That is, why the hell is this call not synchronous, the operator waiting for a second ends up in another thread, and the caller continues without any pauses.
And so that you should write like this:
yield return StartCoroutine(.... etc.
Or instead of calling a coroutine, write
yield return new WaitForSeconds(1);

V
VoLandMonk, 2019-02-22
@VoLandMonk

This is how it will work:

void ChangePos(List<Vector2> pointss, GameObject temp)
    {
        for (int i=0; i<pointss.Count; i++)
        {
            StartCoroutine(ExecuteAfterTime(1, i));
            
        }
    }

    IEnumerator ExecuteAfterTime(int second, int incr)
    {
        yield return new WaitForSeconds(second);
        temp.transform.position = pointss[incr];
    }

Y
Yuri Esin, 2019-02-24
@Exomode

Yes, shove the cycle into the coroutine and call it once, why do you fence such constructions?
In general, in the latest versions it has long been possible to do this:

async Task ChangePos(List<Vector2> pointss, GameObject temp)
    {
        for (int i = 0; i < pointss.Count; i++)
        {
            temp.transform.position = pointss[incr];
            await Task.Delay(1000);
        }
    }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question