Resumen de introducción a UniRx en Unity

¿Qué es UniRx?

  UniRx es la versión de Unity de Reactive Extensions. Reactive Extensions en chino significa: Responsive Extensions. Reactive se refiere a observadores y cronómetros. Las extensiones se refieren a operadores LINQ. Reactive Extensions es famoso por su lógica asíncrona y su estilo API minimalista.

¿Por qué usar UniRx?

  Debido a que muchas operaciones lógicas en el proyecto deben procesarse de forma asíncrona en el tiempo, a menudo hay más lógicas asíncronas que deben implementarse. Por eso existe el concepto de Ctrip.
  En el proyecto, como la reproducción de animación, la solicitud de red, la carga de recursos, la transición de escena, etc., son lógicas que funcionan de forma asincrónica en el tiempo. Cuando implementamos los módulos funcionales anteriores en el proyecto, a menudo usamos una gran cantidad de devoluciones de llamada para implementar, lo que puede causar que el proyecto se llene con una gran cantidad de devoluciones de llamada para manejar alguna lógica. Un método relativamente bueno es implementar mensajes/eventos prácticos, pero el resultado también puede generar una gran cantidad de eventos en el proyecto. Después de un período de tiempo, es posible que no entiendas la lógica que escribiste. .
  La aparición de UniRx acaba de resolver este problema, se encuentra entre las devoluciones de llamada y los eventos.

  • Tiene el concepto de eventos, pero sus eventos son como agua que fluye. Necesitamos organizar, transformar, filtrar, fusionar y otras operaciones sobre estos eventos durante el proceso de desarrollo.
  • También utiliza devoluciones de llamada, pero sus devoluciones de llamada solo deben llamarse una vez para procesar el evento después de que se organice el evento.

API comunes

Función de temporización

En proyectos ordinarios, a menudo se puede encontrar que algunas operaciones lógicas se activan después de un período de tiempo. Por lo
general, es posible usar rutinas

 void Start()
    {
    
    
        StartCoroutine(Timer(10, DoSomething));
    }
    
    IEnumerator Timer(float seconds,Action callback)
    {
    
    
        yield return new WaitForSeconds(seconds);
        callback();
    }

         
    void DoSomething()
    {
    
    
        Debug.Log("TODO");
    }

La declaración del código implementa la misma función que la anterior, después de 10 segundos para imprimir, el código no es muy claro.

 void Start()
    {
    
    
        Observable
            .Timer(TimeSpan.FromSeconds(10))
            .Subscribe(e => {
    
    
                Debug.Log("DoSomething");
            });
    }

  Otra cosa a tener en cuenta es que el método de escritura anterior no está vinculado al ciclo de vida de MonoBehaviour en Unity. Tal vez después de que se destruya MonoBehaviour, la lógica aún se está ejecutando, lo que puede causar un puntero nulo. Debe agregarse al final .AddTo(this)Cuando se destruye el ciclo de vida, la lógica del script también se destruirá. Este es también el punto al que generalmente debemos prestar atención cuando escribimos lógica.
el código se muestra a continuación

 void Start()
    {
    
    
        Observable
            .Timer(TimeSpan.FromSeconds(10))
            .Subscribe(e => {
    
    
                Debug.Log("DoSomething");
            })
            .AddTo(this);
    }

Actualizar

  Al escribir un módulo funcional, se puede definir cierta lógica en Update y la cantidad de código en Update puede ser grande con el proyecto. Con UniRx puedes mantener tu código independiente el uno del otro. De la siguiente manera: ( 注意不要忘记在最后添加.AddTo(this))

void Start()
    {
    
    
        Observable
            .EveryUpdate()
            .Subscribe(e => {
    
    
                Debug.Log("QQQ");
            })
            .AddTo(this);

        Observable
           .EveryUpdate()
           .Subscribe(e => {
    
    
               Debug.Log("WWW");
           })
           .AddTo(this);

        Observable
           .EveryUpdate()
           .Subscribe(e => {
    
    
               Debug.Log("EEE");
           })
           .AddTo(this);
    }

Los códigos anteriores se pueden definir por separado a través de la división de módulos comerciales en proyectos reales, lo que también es conveniente para el mantenimiento futuro.

operadorprimero

En proyectos ordinarios, también puede encontrar funciones relacionadas que deben ejecutarse por primera vez pero no más tarde. Para la implementación convencional, podemos definir un valor bool y asignarlo a falso después de la ejecución una vez. Tome el primer clic del mouse como ejemplo. La palabra clave es First. el código se muestra a continuación

  void Start()
    {
    
    
        Observable
            .EveryUpdate()
            .First(_=>Input.GetMouseButtonDown(0))
            .Subscribe(e => {
    
    
                Debug.Log("EEE");
            })
           .AddTo(this);
    }

operadorDónde

Este Dónde puede entenderse como que sólo puede ejecutarse cuando se cumplen ciertas condiciones. El código es el siguiente, imprime la salida cuando se presiona el botón izquierdo del mouse.

void Start()
{
    
    
	 Observable
            .EveryUpdate()
            .Where(_ => Input.GetMouseButtonDown(0))
            .Subscribe( _=>
            {
    
    
                Debug.Log("DOSomething");
            })
            .AddTo(this);
}

Propiedad reactiva

  ReactiveProperty es el significado de propiedades receptivas. Como su nombre lo indica, al asignar un valor a una propiedad en el proyecto, ejecutará dinámicamente la lógica relevante y cargará directamente el código. ¿Cuáles son las limitaciones del siguiente código? Cuando el valor cambia , el método correspondiente solo se puede realizar dentro de la propiedad Respuesta, ¿y si quiero hacer una llamada externa? Eso puede requerir definir un delegado para el enlace. UniRx tiene una API más concisa;
escritura convencional

 	private int age;
    public int Age
    {
    
    
        get
        {
    
    
            return age;
        }

        set {
    
    
            if (value>0)
            {
    
    
                age = value;
                OnAgeChanged();

            }
        }
    }

    void OnAgeChanged()
    {
    
    
    }

uso de UniRx

	public ReactiveProperty<int> Age = new ReactiveProperty<int>();
    void Start()
    {
    
    
        Age.Subscribe(age =>
        {
    
    
            Debug.Log("赋值之后改变的方法");
        });

        Age.Value = 22;
        }

Soporte para UGUI

Puede usar UniRx para vincular dinámicamente los controles de la interfaz de usuario y puede consultar otros usos usted mismo. También se pueden agregar operadores como Where, , etc. durante la definición de acuerdo con los requisitos comerciales.First

 public Button btn;
    public Toggle toggle;


    void Start()
    {
    
    
        btn.OnClickAsObservable()
            .Subscribe(_ =>
            {
    
    
                Debug.Log("BtnClick");
            });

        toggle.OnValueChangedAsObservable()
            .Subscribe(isOn =>
            {
    
    
                if (isOn)
                {
    
    

                }
                else
                {
    
     }

            });
            }

Fusión de operadores

Lo que se introduce aquí es fusionar la lógica de flujo definida por UniRx. El código es el siguiente: El código define dos flujos de eventos, que se fusionan mediante el operador Merge. Cuando se presiona el botón izquierdo o derecho del mouse, se imprimirá .

 void Start()
    {
    
    
        //定义流1
        var stream01 = Observable
            .EveryUpdate()
            .Where(_ => Input.GetMouseButtonDown(0));
        //定义流2
        var stream02 = Observable
            .EveryUpdate()
            .Where(_ => Input.GetMouseButtonDown(1));

        Observable.Merge(stream01, stream02)
            .Subscribe(_ => {
    
    
                Debug.Log("DoSomeThing");
            })
            .AddTo(this);
     }

El uso básico se introduce aquí.

Supongo que te gusta

Origin blog.csdn.net/weixin_44446603/article/details/125963100
Recomendado
Clasificación