- Home /
Coroutine runs Very Slow for First time Call
its very odd.i have a very simple function like this to move a game object from Point A to B:
IEnumerator Move(GameObject go, Vector3 startPos, Vector3 endPos, float speed)
{
float step = (speed / (startPos - endPos).magnitude) * Time.fixedDeltaTime;
UnityEngine.Debug.Log("step : " + step);
float t = 0;
while (t <= 1.0f)
{
t += step; // Goes from 0 to 1, incrementing by step each time
go.transform.position = Vector3.Lerp(startPos, endPos, t);
yield return new WaitForFixedUpdate();
}
}
and i call it Like This :
StartCoroutine(Move(PlayerGameObject, PlayerGameObject.transform.position , tmpPos, 25);
the first time call is very Slow no matter what the speed is , even2000.
but when i call it again with exactly same parameters it runs perfectly good as expected.
any idea about this? am i missing somthing?
according to https://forum.unity.com/threads/startcoroutine-expensive-on-first-invoke.392652/ it seems the first call is resource expensive naturely. any idea to fix this?
Answer by Bunny83 · Mar 14, 2018 at 12:44 PM
To first address the forum post you mention in the comment: The overhead at the start is mostly related to the fact that the coroutine scheduler most likely hasn't been initialized yet. However the overhead is completely neglectable "0.95 ms" for the first time is nothing. It's about 1/1000th of a second.
When you say "slow" you mean "slow over time", right? Have you checked that your "step" value is actually the same for two calls? Even fixedDeltaTime is usually a constant you should never read it only once and store it in a variable. Also you never really need to directly access fixedDeltaTime (except if you want to change the physics framerate). Time.deltaTime will return the fixedDeltaTime when used inside a Fixed update context. However be warned that your first iteration is not called within the physics loop as it's called immediately when you start the coroutine.
I don't see any reason why you would run this code in fixed update. It's not physics related at all so using fixedupdate will just make it look more choppy because it's not in sync with the visual update. Though if (for whatever reason) you want to keep it in fixedupdate do this:
IEnumerator Move(GameObject go, Vector3 startPos, Vector3 endPos, float speed)
{
float step = (speed / (startPos - endPos).magnitude);
float t = 0;
var trans = go.transform;
var waitFFU = new WaitForFixedUpdate();
// make sure we are inside the fixed update cycle
yield return new WaitForFixedUpdate();
while (t <= 1.0f)
{
t += step * Time.deltaTime;
trans.position = Vector3.Lerp(startPos, endPos, t);
yield return waitFFU;
}
}
If you want to run this every frame (which would be better), do this:
IEnumerator Move(GameObject go, Vector3 startPos, Vector3 endPos, float speed)
{
float step = (speed / (startPos - endPos).magnitude);
float t = 0;
Transform trans = go.transform;
while (t <= 1.0f)
{
t += step * Time.deltaTime;
trans.position = Vector3.Lerp(startPos, endPos, t);
yield return null;
}
}
Won't using Time.deltaTime
within that first block with a yield instruction of WaitForFixedUpdate apply an incorrect time normalization?
Also, OP's block itself isn't explicitly calling physics operations, but OP might expect collider interactions during the movement of this object and need to use the FixedUpdate cycle for that reason.
Your answer
Follow this Question
Related Questions
Coroutines IEnumerator not working as expected 2 Answers
understanding coroutines 0 Answers
How to force Coroutine to finish 1 Answer
Coroutines and states 1 Answer
Why doesnt my coroutine ever end? 2 Answers