Using ECMAScript4 (ActionScript3) to achieve Unity's hot update -- CustomYieldInstruction custom interrupt instruction

In order to facilitate the development of hot update logic, the ActionScript3 script engine provides the function of inheriting the Unity class library from the script, which can provide development convenience in some cases.

This time, let's create an example to demonstrate how to customize the coroutine interrupt instruction in the script

Coroutines in Unity

Coroutines are often used in unity. Essentially, when calling startCoroutine, the incoming parameter is an object that implements the IEnumerator interface.

The IEnumerator interface is a collection accessor that can access all objects in the collection using code similar to the following.

System.Collections.IEnumerator ie;
while (ie.MoveNext())
{
    var item = ie.Current;
}

Among them, each time MoveNext() is called, it will access an object, but this MoveNext() can be determined when it is called, not necessarily in a loop.

You can also decide to execute it once per frame, or even wait for a certain condition to be met before continuing, and so on.

In this way, the coroutine can naturally amortize a series of operations to be executed in multiple frames, giving a multi-threaded effect, but this is not multi-threading.

yield keyword

yield is a syntactic sugar provided by C# 2.0. It allows convenient creation of a method that returns an object of the IEnumerator interface.

If the method is declared to return the IEnumerator interface, within the body of the method, you can use yield to instruct the compiler to create a collection element, add the object we return with yield to the collection, and automatically generate and return an object that implements the IEnumerator interface.

Using yield can be very convenient to create IEnumerator interface objects.

Waiting conditions for Unity coroutines

As mentioned earlier, each time the IEnumerator interface is accessed, the current collection object can be obtained. This current collection object is used by Unity to make a fuss,

It is used to indicate Unity's next operation behavior for this coroutine, such as continuing to wait, or calling MoveNext to advance the method in the coroutine to the next step.

CustomYieldInstruction Custom interrupt instruction 

CustomYieldInstruction implements a custom interrupt instruction to suspend coroutine execution until an event occurs. To achieve this, you need to inherit from the CustomYieldInstruction class and override the keepWaiting property.

Returns true if you want to keep the coroutine suspended, and returns false if you want the coroutine to continue executing.

Implemented in hot update script

According to the Unity example, it shows that when the left mouse button is clicked, a coroutine is started, and then the coroutine waits until the right mouse button is clicked to continue execution.

We can directly implement the above logic in hot update.

  1. Create a new hotfix project. If not created, refer to here
  2. Change the Main.as code to the following code:
    package
    {
        /**
         * ...
         * @author
         */ 
        public  class Main
        {        
            public function Main() {}        
            public function update():void {}        
        }
    }
    
    import unityengine.Camera;
    import unityengine.CustomYieldInstruction;
    import unityengine.Input;
    import unityengine.MonoBehaviour;
    
    // Example showing how a CustomYieldInstruction script file
    // can be used.  This waits for the left button to go up and then
    // waits for the right button to go down.
    
    class ExampleScript extends MonoBehaviour
    {
        function Update():void
        {
            // When the left button is clicked, start the coroutine. waitForMouseDown 
            if (Input.getMouseButtonUp(0 ))
            {
                trace("Left mouse button up");
                startCoroutine(Iterator(waitForMouseDown())); // The coroutine needs to be wrapped with Iterator. 
            }
        }
    
        function waitForMouseDown()
        {
            // Use a custom CustomYieldInstruction subclass. 
            yield return  new WaitForMouseDown();
            trace("Right mouse button pressed");
        }
    }
    
    class WaitForMouseDown extends CustomYieldInstruction
    {
        override public function get keepWaiting():Boolean 
        {
            // When no right click is detected, keep waiting. 
            return !Input.getMouseButtonDown(1 );
        }
    
        public function WaitForMouseDown()
        {
             trace("Waiting for Mouse right button down");
        }
    }
    
    // Test script. 
    Camera.main.gameObject.addComponent(ExampleScript);

     

  3. Compile the code and hit execute in Unity.
  4. The running result is as follows

     

So, we understand how to operate coroutines in hot update

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325020148&siteId=291194637