I want an action to be performed in update function , such as turning the screen black for specific period of time , I don’t want update to go ahead and perform other actions (run functions ahead of this function ), I want this function to completely run for like 10 ms , before performing next action. Can i do this with coroutine ? .
2 Answers
2Yes. That’s exactly the sort of common use-case for coroutines.
Coroutine is commonly used to perform time based action. Though it can be cumbersome when you want to chain several actions one after the other. And coroutines become nearly unmanageable when you introduce some conditional branching or want to cancel some action.
If you are doing a lot of these timely logics, I would suggest to consider Behaviour Tree. I’ve made a scripting framework based on this technique: Panda BT (www.pandabehaviour.com).
As an example, let’s say you want to make a traffic light, which cycle through red, green and yellow and each color change takes some time to complete.
First you need to define a [Task], which is equivalent to a coroutine but less simpler. A [Task] function is called at each frame until Task.current.Succeed() is called, which indicates that the task is done. The task to change color would be:
using UnityEngine;
using Panda;
public class TrafficLight : MonoBehaviour
{
public float duration = 1.0f;
[Task]
void ChangeColor(float r, float g, float b)
{
if (Task.current.isStarting)
{
startTime = Time.time;
startColor = material.color;
endColor = new Color(r, g, b);
}
float elapsedTime = Time.time - startTime;
float t = elapsedTime / duration;
material.color = Color.Lerp(startColor, endColor, t);
if (elapsedTime > duration)
Task.current.Succeed();
}
Material material;
float startTime;
Color startColor;
Color endColor;
void Start()
{
material = GetComponent<Renderer>().material;
}
}
Then you can use this [Task] into a BT script to define the behaviour of your traffic light:
tree("root")
sequence
ChangeColor(1.0, 0.0, 0.0) // turn red
ChangeColor(0.0, 1.0, 0.0) // turn green
ChangeColor(1.0, 1.0, 0.0) // turn yellow
Note that you can do more than sequences with behaviour tree. But that would be out of the scope of this answer to detail that here. If you have any question, you’re welcome on this thread.
I would not opt for coroutines in that case. That would mean you always have a coroutine running and it needs to know what should be the next coroutine to start based on a state.Also, many coroutines bring GC issue. I would go more for a state-machine approach like ericbegue proposed and kinda what I proposed too (in a simplified way).
– fafase