Article Directory
Preface
We know that the code in Unity is roughly executed in a frame-by-frame loop. In general, the logic in a method will be executed within one frame, so what if we need to delay the execution of a certain piece of code? What?
Of course, we can set a timer variable by ourselves, update every frame, and execute the code block at the right time. This processing is undoubtedly possible, but if there are a lot of objects that need to be timed, this processing is It will inevitably become troublesome, so is there any simple way to achieve this requirement?
Coroutine (coroutine) can easily solve this problem.
The concept of coroutine
To understand the coroutine, you must first understand the concept of threads and processes:
Process : The basic unit of the system for resource allocation , in layman's terms, is one application after another ;
Thread : It is the component unit of the process, it is a sequential command execution flow, so it can also be regarded as the smallest unit of the system for command execution and resource allocation
To aid understanding, let's take a look at Win10's Resource Monitor:
The exe that the system allocates memory is a process, and they are composed of a thread, and a thread is composed of a plurality of code blocks to execute logic commands. A
single thread is executed sequentially. Obviously, we don’t have only linear requirements. , When we need multiple tasks to be executed at the same time, the concept of multithreading appears
The coroutine is a kind of "pseudo multithreading" operation used to realize "multithreading" in C#
Let us first come to a simple coroutine to have a preliminary look at the effect of the coroutine:
public class SimpleCoroutine : MonoBehaviour
{
private int count = 0;
void Start()
{
StartCoroutine(CoroutineTest());
}
void Update()
{
count += 1;
print("Count : " + count);
}
IEnumerator CoroutineTest()
{
for (int i = 0; i < 5 ;i++ )
{
print("i : " + i);
yield return null;
}
}
}
Let’s analyze this code,
First, a global variable count is declared , its initial value is 0 , and its value is incremented by 1 in each frame in the Updata() method , and its value is printed on the console
Declares a method using CoroutineTest coroutine () , it is less than 5 until the value of i in a for loop , every time i is incremented by one to print a value of i , in which the script is performed starting Start () method
The result of this script execution is as follows: As
you can see, the value of i and the value of Count are printed alternately
If you look at it in a normal linear order, the CoroutineTest method started in the Start method should have completed all the printing before printing the first Count, and now the alternate printing result shown in the figure above is realized by the coroutine The effect is-it makes the content of the for loop in the CoroutineTest method a frame-by-frame delay.
Use of coroutines
Declaration of coroutine method
Just like the way to declare CorotineTest() in the example in the previous part
To process a code block using a coroutine, you first need to return the method it is in to an IEnumerator type.
Because the coroutine is actually implemented by iterators, the underlying things will not be discussed here.
Then what needs to be done is to add a yield return statement where you want it to be temporarily interrupted , and the return value is any value that is not a subclass of the YieldInstruction class (null, 1 or 0 is recommended), its effect is all Is delayed by one frame
The subclasses of the YieldInstruction class include the following: the
effect can be clearly seen from the name, so I won’t repeat them one by one.
The more commonly used is the WaitForSeconds class:
yield return new WaitForSeconds(float seconds);
Just return in this form. The seconds parameter of the float type determines the duration of the interruption, in seconds.
Enabling the coroutine
To enable a coroutine, use the StartCoroutine() method encapsulated in the Behaviour class. It has the following two overloads:
StartCoroutine(string methodName);
StartCoroutine(IEnumerator routine);
The first is to use string type method names as parameters
The second is to directly receive the IEnumerator type returned by the target method
But we noticed that this method does not have parameters, so how to enable a method that requires parameters?
There is also such an overload in the StartCoroutine() method that uses string type as a parameter:
StartCoroutine(string methodName, [DefaultValue(“null”)] object value);
The parameter value with the default value of null will be used as the target method parameter to participate in the activation of the coroutine
The stop of the coroutine
Naturally, when there is a start, there is a stop-the StopCoroutine() method, which is also encapsulated in the Behaviour class, and the overloading methods are mainly as follows:
StopCoroutine(IEnumerator routine)
StopCoroutine(string methodName)
But it should be noted that it can only be used to stop those methods that use string type parameters to enable methods
summary
The main function of a coroutine is to delay the execution of a code block, so its common scenario is when a simple timer needs to be implemented or a large number of calculations are delayed.