concepto
C#
En , los eventos event
se utilizan para implementar un mecanismo de devolución de llamada basado en delegados.
Los eventos permiten que los objetos notifiquen a otros objetos que se han producido operaciones específicas y, opcionalmente, estos objetos pueden responder a esas operaciones.
Los eventos se utilizan a menudo para implementar un modelo de publicación-suscripción donde un objeto ( el publicador ) emite un evento y otros objetos ( suscriptores ) escuchan el evento y realizan sus acciones cuando ocurre el evento.
Escenario de aplicación:
Supongamos un escenario, ahora hay una actualización de personaje como se muestra en la figura a continuación, y la actualización debe ser suficiente exp
:
- Si
获得的exp
<升级所需的exp
, el editor indica que la experiencia no es suficiente, entonces el suscriptor la ignora; - si
获得的exp
≥ \ge≥升级所需的exp
, entonces los suscriptores tendránlos efectos de pantalla de actualización.
Además del ejemplo de subir de nivel, también hay aplicaciones como árboles de habilidades, uso de elementos, etc.
Ventajas del evento
- El desacoplamiento de editores y suscriptores para que no necesiten conocer la implementación del otro hace que el sistema sea más flexible y más fácil de mantener y ampliar.
- Los eventos también proporcionan una forma uniforme de ampliar la funcionalidad de las clases.
Al ver las ventajas anteriores, es posible que Xiaobai no sepa de qué está hablando, no se preocupe, sigamos mirando hacia abajo.
Cómo crear un evento
C#
En , los eventos se componen de palabras clave de delegado y evento. Entonces un proceso básico es el siguiente:
- Al declarar un evento, primero debe declarar un tipo de delegado y luego usar
event
la palabra clave para declarar el tipo de delegado como un evento. - Los suscriptores pueden agregar sus métodos a la lista de delegados del evento usando
+=
el operador que se llamará cuando ocurra el evento. - Los publicadores pueden desencadenar eventos invocando la lista de delegados del evento.
A continuación, se muestran CodeMonkey
ejemplos de eventos de C# conocidos:
Paso 1: Cree scripts de C# para que los editores y los suscriptores AddComponent
compartan lo mismoGameObject
Paso 2: Definir un editor
Defina tres eventos.
OnSpacePressed
Evento, que es un tipo de delegado con unOnSpacePressedArgs
parámetroEventHandler
que representa un evento que ocurre cuando se presiona la barra espaciadora.OnFloatEvent
Evento, el evento es unTestEventDelegate
tipo de delegado, lo que significa un evento que se puede desencadenar en cualquier momento.OnActionEvent
Evento, el evento es unAction
tipo de delegado con parámetrosbool
yint
, lo que indica que el evento se puede desencadenar en cualquier momento.
Método de actualización
Si detecta que se presiona la barra espaciadora, se disparará el evento OnSpacePressed、OnFloatEvent和OnActionEvent
.
En OnSpacePressed
el evento ( incluido el contenido del comentario ), use EventArgs.Empty
el parámetro pasar vacío para indicar que este evento no requiere ningún parámetro, pero también podemos usar parámetros personalizados OnSpacePressedArgs
.
En OnFloatEvent
eventos y OnActionEvent
eventos, use Invoke
métodos para desencadenar eventos y pase los parámetros necesarios a los métodos de manejo de eventos.
TestingEvents.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class TestingEvents : MonoBehaviour
{
// 声明一个事件
public event EventHandler<OnSpacePressedArgs> OnSpacePressed;
public class OnSpacePressedArgs : EventArgs
{
public int spaceCount;
}
private int spaceCount;
public event TestEventDelegate OnFloatEvent;
//定义一个委托类型
public delegate void TestEventDelegate(float f);
public event Action<bool, int> OnActionEvent;
//统一的安全API,方便定义委托类型
public UnityEvent OnUnityEvent;
// Start is called before the first frame update
void Start(){
}
// Update is called once per frame
// 在触发事件
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
spaceCount++;
//Space pressed!
//if(OnSpacePressed!= null) OnSpacePressed(this,EventArgs.Empty);
OnSpacePressed?.Invoke(this, new OnSpacePressedArgs {
spaceCount = spaceCount});
OnFloatEvent?.Invoke(5.5f);
OnActionEvent?.Invoke(true,56);
OnUnityEvent?.Invoke();
}
}
}
Paso 3: Implementar los suscriptores correspondientes
método de inicio
Suscríbase a los tres eventos mencionados y, en Start
el método, obtenga TestingEvents
el componente y TestingEventSubscriber
asocie sus eventos con los métodos de la clase para que se ejecuten cuando se dispare el evento. Los eventos suscritos aquí son respectivamente OnSpacePressed、OnFloatEvent和OnActionEvent
.
Definir métodos para manejar estos tres eventos.
Cuando se dispara un evento, estos TestingEvents_OnSpacePressed、TestingEvents_OnFloatEvent和TestingEvents_OnActionEvent
métodos se invocarán con los parámetros esperados por su evento correspondiente.
Cada método tiene un comportamiento específico, por ejemplo, dentro de TestingEvents_OnSpacePressed
un método, se genera un mensaje de depuración con el número de pulsaciones de la barra espaciadora.
metodo publico
TestingEventSubscriber
La clase también define un TestingUnityEvent
método público llamado , que simplemente genera un mensaje de depuración para demostrar cómo usar el método como controlador de eventos.
TestingEventSubscriber.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestingEventSubscriber : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//作为获得订阅的行为
TestingEvents testingEvents =GetComponent<TestingEvents>();
testingEvents.OnSpacePressed += TestingEvents_OnSpacePressed;
testingEvents.OnFloatEvent += TestingEvents_OnFloatEvent;
testingEvents.OnActionEvent += TestingEvents_OnActionEvent;
}
public void TestingUnityEvent()
{
Debug.Log("TestingUnityEvent");
}
private void TestingEvents_OnActionEvent(bool arg1,int arg2)
{
Debug.Log(arg1 + " " + arg2);
}
private void TestingEvents_OnFloatEvent(float f)
{
Debug.Log("Float:" +f );
}
private void TestingEvents_OnSpacePressed(object sender, TestingEvents.OnSpacePressedArgs e)
{
Debug.Log("Space!"+e.spaceCount);
//取消订阅
//TestingEvents testingEvents = GetComponent<TestingEvents>();
//testingEvents.OnSpacePressed -= TestingEvents_OnSpacePressed;
}
// Update is called once per frame
void Update(){
}
}
Ignorado por no novatos: la barra para mirar unity
al depurarconsole
Nota: ¿Cómo usar métodos públicos?
Encuentre el suyo primero GameObject
, luego elija su método público
Volver a dudas anteriores
El llamado desacoplamiento, ¿puede observar por qué el editor no usa el método de inicio? En su lugar, utilice el método updata
porque no queremos escribir la implementación del suscriptor en la clase del editor.
El método público es en realidad una API, solo úselo.
Por supuesto, no respondas así la pregunta del entrevistador, la gente te despreciará cuando vea que tu respuesta es tan simple.
socio cooperativo
Potente manual solo puede chatGpt3.5
referencia
Video de C# Basic de CodeMonkey, analizado por un 2$/month
humilde estudiante.