[Unity learning process 5] Use C# in Unity to quickly and easily implement timing: Coroutine (coroutine)

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:

Win10 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
Coroutine method execution result
    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
YieldInstruction子类
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.

Guess you like

Origin blog.csdn.net/Jourofant/article/details/108759386