- Home /
Yield not working properly
I'm working on a pathfinding/waypoints script. I move from waypoint to waypoint with a loop, that does a linear interpolation and yields every frame. This works perfectly, until I reach the first waypoint. After that, it will execute the whole loop without yielding - or at least, that's what I've observed through debugging.
void Update()
{
currentPosition = transform.position;
targetPosition = waypoints[currentWaypoint].waypoint.position;
StartCoroutine(GetNextPos());
if (currentPosition == targetPosition)
{
currentWaypoint = Mathf.Clamp(currentWaypoint + 1, 0, waypoints.Length - 1);
startPosition = currentPosition;
targetPosition = waypoints[currentWaypoint].waypoint.position;
}
}
IEnumerator GetNextPos()
{
float x = 0f;
while (x <= 1.0f)
{
x += Time.deltaTime * speed;
transform.position = Vector3.Lerp(startPosition, targetPosition, x);
yield return null;
}
}
Not sure, but you may need to yield to GetNextPos() like so:
yield return StartCoroutine(GetNextPos());
This page explains the difference:
@AchillesWF you cannot yield
inside Update
. But you can certainly do it inside Start
, which is what I propose in my answer.
Thank you for the correction. Yes, of course to use yield the return value of the function must be IEnumerator and Update() therefore does not qualify.
Answer by Kryptos · Apr 22, 2012 at 03:13 PM
It is really a bad idea to call StartCoroutine
inside Update()
without proper control. Each frame you will start a new coroutine which is not what you want. Because after 50 frames you will have 50 coroutines that are executed concurrently.
I don't know exactly what you want to do, but consider this kind of solution instead that use the Start()
method which here is also a coroutine:
IEnumerator Start()
{
while (aCondition)
{
yield return StartCoroutine(GetNextPos());
aCondition = (some test and value check);
}
}
IEnumerator GetNextPos()
{
// your code here
// populate some member variable to help decide when to start this coroutine again
}
edit: in your case aCondition
will be to check whether you reached the last waypoint. And between two calls to GetNextPos()
, you can set the start/end values, the same way you do inside the if
statement in your Update()
method.
I do need this in my Update(), because I have to update other variables as well. If it helps explaining, it's for a tower defence game.
Also, what's the point of returning my coroutine itself? EDIT: never $$anonymous$$d, didn't notice Start was a coroutine as well.
As I explain in my answer. Start can be a coroutine and act like an Update method but with yield statements. This is the good way to do it when you use coroutines.
Also, what's the point of returning my coroutine itself?
That's how coroutines work. Read more carefully the documentation and check some tutorials (for example the one about states machines).
It's working! Still need to tweak it a bit, as it's doing each waypoint twice for some reason. But at least I can make some progress now, thank you!
@Simon V: it's highly likely you don't actually need to use Update. You can probably restructure your code to eli$$anonymous$$ate Update in favor of using coroutines, and it will make things more understandable.
Your answer
Follow this Question
Related Questions
How To cycle coroutine in C# say every 1 sec? 2 Answers
[C#]Spawnmanager loop 2 Answers
Playing footsteps with interval 1 Answer
In coroutin function,if(x) { yield return a } . if(y) { yield return b }. Is it possible? 0 Answers
C# Wait for Coroutine 3 Answers