- Home /
move inside a coroutine
Hi,
I want a simple camera moves into vent script. I never used coroutines before and want to make a point of using it for this to get to know them better.
It all runs in a single frame and I teleport into the vent. I know why it does this and understand that although it moves in the steps that I want, the steps all just happen in a single frame.
I basically just want to avoid having the Vector3.MoveTowards in the update in an if statement.
Any help would be greatly appreciated.
{
private IEnumerator EnterVent(Transform ventSpawn)
{
while (cam.position != ventSpawn.position)
{
cam.position = Vector3.MoveTowards(cam.position, ventSpawn.position, speed);
}
this.gameObject.SetActive(false);
ventPlayer.SetActive(true);
return null;
}
}
Answer by s_awali · Sep 26, 2019 at 02:04 PM
That's because you never tell the Coroutine to wait for the next frame to do the operation. Try adding yield return null;
after cam.position = Vector3.MoveTowards(cam.position, ventSpawn.position, speed);
You can also check out my library for easier use of Coroutine: https://github.com/SebastienAwali/SAction
Answer by WarmedxMints · Sep 26, 2019 at 02:13 PM
A coroutine will execute all the code before it returns, just like any other method. So you first need to add yield return null in your while statement.
You also shouldn't compare floats and a Vector3 is just 3 floats at the end of the day so cam.position != ventSapwn.position will be true more than you like. Personally, I would use a lerp. like so;
private IEnumerator EnterVent(Transform ventSpawn, float duration)
{
var startPos = cam.position;
var endPos = ventSpawn.position;
var t = 0f;
while (t <= 1f)
{
cam.position = Vector3.Lerp(startPos, endPos, t);
t += Time.deltaTime / duration;
yield return null;
}
cam.position = endPos;
this.gameObject.SetActive(false);
ventPlayer.SetActive(true);
}
Well, your statements are not quite right. A coroutine will not execute all it's code like a normal method. A coroutine / iterator by definition has to contain at least one yield statement. When this yield statement is reached, the coroutine will return. The coroutine scheduler will schedule the coroutine again "when it's time". When this will be depends on what value you have yielded.
Also while it's generally adviced to avoid float / Vector equallity / inequallity comparisons, in the case of $$anonymous$$oveTowards this usually works perfectly fine. You should avoid exact comparisons if the values you compare are the result of some sort of calculation because due to floating point inaccuracies and rounding two numbers could be lightly off. However $$anonymous$$oveTowards will actually return the target value when the remaining distance is less then the specified delta speed.
The only possible issue in the code in question is, that the value is assigned to transform.position
. If the transform in question is a child of another object this assignment will actually result in a conversion to the local space of the parent and reading transform.position does the opposite. Especially when dealing with rather large numbers this could already cause a slight error. Though if the transform is not a child of anything the code in question would work 100% reliable.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Coroutine Won't Stop Using IEnumerator 1 Answer
Two coroutines in Start(), must exec consecutively 1 Answer
Loop Coroutine For A Demo Mode 1 Answer