事件 Events
事件(Events) 包含 发布者(Publishers) 和 订阅者(Subscribers)
多个订阅者可以订阅同一事件,当发生事件时,发布者 会触发该事件,所有订阅者都会收到事件被触发的通知
特性
发布者不知道有几个订阅者,发布者只管发送,而接收者只管接收
基础示例
/*发布者*/
public class TEvents : MonoBehaviour
{
//事件处理程序
public event EventHandler OnSpacePressed;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
//if(OnSpacePressed != null)
//{
// OnSpacePressed(this, EventArgs.Empty);
//}
//?.Invoke [空值传播运算符] 若event不为null则Invoke
OnSpacePressed?.Invoke(this, EventArgs.Empty);
}
}
}
/*订阅者*/
public class TEventSubscriber : MonoBehaviour
{
public TEvents tEvents;
private void Start()
{
//注册方法
tEvents.OnSpacePressed += Test_OnSpacePressed;
//注销方法
//tEvents.OnSpacePressed -= Test_OnSpacePressed;
}
/// <summary>
/// 订阅者收到事件触发通知时调用的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Test_OnSpacePressed(object sender, EventArgs e)
{
Debug.Log("订阅者 空格!");
}
}
进阶示例
自定义事件的类(标准流程)
/*发布者*/
public class TEvents : MonoBehaviour
{
//事件处理程序
public event EventHandler<OnSpacePressedEventArgs> OnSpacePressed;
/// <summary>
/// 自定义事件类
/// </summary>
public class OnSpacePressedEventArgs : EventArgs
{
public int SpaceCount;
}
private int spaceCount = 0;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
spaceCount++;
OnSpacePressed?.Invoke(this, new OnSpacePressedEventArgs { SpaceCount = spaceCount});
}
}
}
/*订阅者*/
public class TEventSubscriber : MonoBehaviour
{
public TEvents tEvents;
private void Start()
{
tEvents.OnSpacePressed += Test_OnSpacePressed;
}
private void Test_OnSpacePressed(object sender, TEvents.OnSpacePressedEventArgs e)
{
Debug.Log($"订阅者 空格! {e.SpaceCount}");
}
}
事件本质是一种委托,自定义委托
/*发布者*/
public class TEvents : MonoBehaviour
{
//事件处理程序
public event TestEventDelegate OnFloatEvent;
//定义个自定义委托
public delegate void TestEventDelegate(float f);
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
OnFloatEvent?.Invoke(12.3f);
}
}
}
/*订阅者*/
public class TEventSubscriber : MonoBehaviour
{
public TEvents tEvents;
private void Start()
{
tEvents.OnFloatEvent += Test_OnFloatEvent;
}
private void Test_OnFloatEvent(float f)
{
Debug.Log($"Float Event: {f}");
}
}
使用Action (Action 是Unity封装的委托类型,没有返回值,可以带参数)
/*发布者*/
public class TEvents : MonoBehaviour
{
//事件处理程序
public event Action<bool, int> OnActionEvent;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
OnActionEvent?.Invoke(true, 12);
}
}
}
/*订阅者*/
public class TEventSubscriber : MonoBehaviour
{
public TEvents tEvents;
private void Start()
{
tEvents.OnActionEvent += Test_OnActionEvent;
}
private void Test_OnActionEvent(bool arg1,int arg2)
{
Debug.Log($"{arg1} {arg2}");
}
}
UnityEvent
方便在编辑器操作
/*发布者*/
public class TEvents : MonoBehaviour
{
//事件处理程序
public UnityEvent OnUnityEvent;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
OnUnityEvent?.Invoke();
}
}
}
/*订阅者*/
public class TEventSubscriber : MonoBehaviour
{
public void Test_UnityEvent()
{
Debug.Log("UnityEvent!");
}
}