Profundo conocimiento de las corutinas de Unity

Las corutinas son compatibles con muchos lenguajes de programación, por ejemplo, en Lua que mencionamos anteriormente, las corutinas son una tecnología de subprocesamiento virtual.


Breve descripcion


Piense en lo que generalmente mencionamos cuando compramos una computadora. La CPU tiene cuatro núcleos y ocho hilos. De hecho, la CPU solo puede manejar una cosa. Es decir, la CPU por defecto es un núcleo para un hilo, pero si necesitamos procesar múltiples Tareas, y no tenemos tantos hilos.
Luego, la gente presenta el concepto de subprocesos virtuales, virtualiza un solo subproceso de la CPU y crea múltiples subprocesos, de modo que tengamos los conceptos de cuatro núcleos y ocho subprocesos, ocho núcleos y dieciséis subprocesos; también hay subprocesos en el lado de la aplicación. Y el concepto de proceso, después de subdividir el proceso, el hilo del software de virtualización tiene el concepto de rutina.

Ahora ya sabe que las corutinas son la subdivisión de hilos, y son la virtualización de hilos.

 Unidad de rutina


Aunque el concepto de corutinas no es novedoso, el término "corutinas" rara vez puede estar involucrado en el campo actual de desarrollo de Internet.
Coroutine es trabajar juntos para lograr una cosa. Es fácil pensar en el concepto de subprocesamiento múltiple. Por ejemplo, cuando hacemos una solicitud de red, debemos esperar la respuesta antes de la próxima operación. En este momento, usaremos hilos 'mutexes' y '. Concepto de seguridad, etc.
En la unidad o en el motor del juego, debido a las limitaciones del hilo principal del juego, es imposible garantizar la seguridad de los subprocesos múltiples. En este momento, es particularmente importante continuar utilizando las rutinas para realizar trabajos de subprocesos múltiples bajo el mismo hilo.
(Unity también se retiró del modo ECS de rendimiento primero, abandonó el marco Mono e implementó un modo de desarrollo que puede ser asistido por un desarrollo de subprocesos múltiples).
A continuación, presentaremos principalmente las corutinas de la unidad en detalle.

 Ejemplo de unidad de rutina


Mira este ejemplo:

//创建协程
private IEnumerator Cor1()
{
    yield return new WaitForSeconds(2f);
    Debug.Log("2s到了");
}
//启动协程
StartCoroutine(Cor1());


Este es un ejemplo simple, puede ver que la rutina necesita devolver un objeto iterable `IEnumerator`, que originalmente era la implementación del patrón iterador en Csharp, y Unity implementó la rutina como un prototipo en la unidad.

 Parámetros de corutinas.


En lo anterior utilizamos `new WaitForSeconds ()`, lo que significa esperar el tiempo especificado. [Tenga en cuenta que WaitForSeconds está relacionado con Time.Scale]
Hay muchos parámetros distintos de WaitForSeconds utilizados anteriormente. Estos parámetros toman tiempo o devuelven bool. En resumen, debe determinar un moveNext.


Uso de corutinas

 

1. Se usa para situaciones de duración incierta (por ejemplo: solicitudes de red, lectura y escritura de archivos)
2. Para ejecución retrasada
3. Se puede usar como un temporizador simple (por ejemplo: producir un lote de enemigos)

 Anidamiento de rutina


Las corutinas admiten el anidamiento. La siguiente es una implementación simple de patrullaje usando corutinas.
** Nota: en la unidad, la rutina devuelve 0 o nulo para esperar el siguiente fotograma. ** **

using System;
using System.Collections;
using UnityEngine;

namespace Coroutines
{
    //协程测试
    public class CoroutTest : MonoBehaviour
    {
        public Transform[] wayPoints;

        private bool isLoop;

        private void Start()
        {
            isLoop = true;
            StartCoroutine(StartLoop());
        }

        private IEnumerator StartLoop()
        {
            do
            {
                foreach (var point in wayPoints)
                {
                    yield return StartCoroutine(MoveTarget(point.position));
                }
            } while (isLoop);
        }

        private IEnumerator MoveTarget(Vector3 target)
        {
            while (transform.position!=target)
            {
                transform.position = Vector3.MoveTowards(transform.position, target, 3 * Time.deltaTime);
                yield return 0;
            }
        }
    }
}


 Deje que se mueva la corutina

 

+ StartCoroutine (nameof (StartLoop));
inicie la rutina en forma de cadena, puede detener la rutina externamente y no puede pasar parámetros.

+ StartCoroutine (StartLoop);
inicia la rutina en forma de iterador, puede pasar parámetros, no puede detener la rutina con parada externa.

### Deje que se detenga la rutina La
rutina es esencialmente un iterador. Cuando moveNext es falso, todos los elementos de la rutina se han ejecutado.
Hay varias formas de detener las corutinas en la unidad:

1. StopCoroutine () Tenga en cuenta que este método solo puede detener la corutina iniciada en forma de una cadena [usada fuera de la corutina]
2. límite de rendimiento de la corutina [usada dentro de la corutina]
3. Use la lógica para detener [hacer la corutina La condición de ejecución del proceso no se cumple]
4. Establezca el objeto para que esté inactivo [activar la corutina nuevamente no se restaurará]
5. StopAllCoroutine () Terminar todas las corutinas

Como en el ejemplo de anidamiento de la rutina anterior, si queremos que la rutina se detenga:
1. Establezca isLoop = false; deje que se detenga automáticamente si no cumple con las condiciones después de que se ejecute una vez
2. Rompa dentro de la rutina
 

if (transform.position==wayPoints[2].position)
{
    yield break;
}


3. Deténgase fuera de la corutina.
 

 StopCoroutine(nameof(StartLoop));

 La idea de diseño de la corutina.

 ¿Corutina reemplaza la actualización?


A través del ejemplo anterior, puede encontrar que las corutinas son en realidad otra implementación de la actualización. Incluso podemos usarlas sin ninguna actualización y actualización fija para completar la redacción del programa.
Pero si hacemos esto, ¿no es así? Las rutinas son un paradigma de ejecución retrasada introducido por la unidad, que todavía se basa en la capa superior de actualización.

¿Usar corutinas mejorará en gran medida la eficiencia del programa?


No, las corutinas están esencialmente en un subproceso. Aunque se pueden paralelizar múltiples corutinas, estas corrutinas siempre se ejecutan en un subproceso, y la velocidad y eficiencia no mejorarán en gran medida. En cambio, se abren varios subprocesos en paralelo, y el subproceso necesita monitorear el estado de muchas corutinas. Cuando se termina una gran cantidad de corutinas, se activará una gran cantidad de GC, lo que puede reducir la eficiencia del programa.

 Resumen


Una corutina es un subproceso que se ejecuta en un subproceso, y su modo de operación todavía se basa en un solo subproceso, y no mejorará la eficiencia operativa del programa debido al uso de corutinas, pero la forma conveniente de escribir corutinas y las potentes funciones pueden mejorarnos como desarrolladores. Eficiencia de desarrollo.
En cierto sentido, las corutinas son más como un hermoso azúcar sintáctico.

25 artículos originales publicados · Me gusta6 · Visitas 10,000+

Supongo que te gusta

Origin blog.csdn.net/qq_37446649/article/details/105647645
Recomendado
Clasificación