unity学习——事件机制(观察者模式)

C#事件机制与观察者模式
本文通过Unity实例详细介绍了C#中的事件机制及如何使用委托实现观察者模式,以此来降低对象间的耦合度。

在C#中的事件机制便是以委托作为基础的。下面我们来做一个小例子:场景中一个按妞,点击按妞,通过摄像机上的脚本来打印一句话。
1.定义委托类型,确定回调方法原型。
public delegate void buttonDelegate();
2.定义事件成员。
public event buttonDelegate buttonEvent;
3.定义触发事件的方法。
private void Click()
{
Debug.Log(“按妞被点击”);
if (buttonEvent != null)
buttonEvent();
}
4.定义事件的观察者。
eventR类
5.实现观察者模式

!!!eventSub类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class eventSub : MonoBehaviour {
    public Button button;
    public delegate void buttonDelegate();
    public event buttonDelegate buttonEvent;
  protected virtual void Onbutton()
    {

    }

    // Use this for initialization
    private void Click()
    {
        Debug.Log("按妞被点击");
        if (buttonEvent != null)
            buttonEvent();
    }
    private void Start()
    {
        button.onClick.AddListener(Click);
    }

    // Update is called once per frame
    void Update () {

    }
}

eventR类

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class eventR : MonoBehaviour {
    public eventSub sub;

    private void AddListener()
    {
        this.sub.buttonEvent += new eventSub.buttonDelegate(this.Click);
        // Use this for initialization

    }
    private void RemoveListener()
    {
        this.sub.buttonEvent-=new eventSub.buttonDelegate(this.Click);
    }

    private void Click()
    {
        Debug.Log("然后。。。。。");
    }
    private void Start()
    {

        this.AddListener();
    }
}

将eventSub类挂在button上,eventR挂在摄像机上。运行场景
这里写图片描述

点击按妞:
这里写图片描述

通过事件机制可以将对象之间的互相依赖降低到最低,这便是松耦合的威力。而观察者模式的意义同样在于此,它是一种让主题和观察者之间实现松耦合的设计模式:当两个对象之间松耦合,虽然不清楚彼此的细节,但是他们仍然可以交互。在观察者设计模式中,主题只需要了解观察者是否实现了和确定的方法原型想匹配的回调方法,而无须了解观察者的具体类是什么。

Unity 中,委托(Delegate)和事件(Event)是实现对象间通信的重要机制,尤其适用于模块化设计、解耦逻辑以及提升代码的可维护性和可扩展性。通过委托和事件,可以实现多个对象对某一行为的订阅和响应,而无需直接耦合彼此的逻辑。 ### 委托的基本定义与使用 在 C# 中,委托是一种类型安全的函数指针,可以用来封装方法的引用。定义一个委托使用 `delegate` 关键字,例如: ```csharp public delegate void MyDelegate(); ``` 该委托可以指向任何没有参数且返回值为 `void` 的方法。使用委托时,可以通过 `+=` 和 `-=` 操作符来添加或移除方法。 ### 事件的声明与触发 事件基于委托,通常用于实现观察者模式。在 Unity 中,事件通常被声明为静态事件,以便于在不同对象之间共享[^2]。例如: ```csharp public static event MyDelegate OnMyEvent; ``` 在某个特定条件下,比如按键触发时,调用事件: ```csharp private void Update() { if (Input.GetButtonDown("Defend")) { OnMyEvent?.Invoke(); } } ``` ### 订阅与取消订阅事件 订阅事件通常在 `Start` 或 `Awake` 方法中进行,而取消订阅则在 `OnDisable` 或 ` OnDestroy` 中完成,以避免内存泄漏或空引用异常[^2]。 ```csharp private void Start() { MyEventPublisher.OnMyEvent += MyEventHandler; } private void OnDisable() { MyEventPublisher.OnMyEvent -= MyEventHandler; } void MyEventHandler() { Debug.Log("触发委托事件"); } ``` ### 自定义事件参数 在某些情况下,事件需要传递额外的信息。可以通过自定义事件参数类来实现。例如,定义一个事件参数类: ```csharp public class PlayerAniEventArgs : EventArgs { public string AnimationName { get; set; } } ``` 然后定义一个带有自定义参数的委托和事件: ```csharp public delegate void AniChangeHandle(object sender, PlayerAniEventArgs e); public event AniChangeHandle CustomMoveComplete; ``` 在触发事件时传递参数: ```csharp PlayerAniEventArgs args = new PlayerAniEventArgs { AnimationName = "Run" }; CustomMoveComplete?.Invoke(this, args); ``` ### 示例:完整委托事件实现 以下是一个完整的 Unity 委托事件实现示例: ```csharp using UnityEngine; // 定义一个委托 public delegate void MyDelegate(); public class MyEventPublisher : MonoBehaviour { // 定义一个静态事件 public static event MyDelegate OnMyEvent; private void Update() { // 检测是否按下防御键——C if (Input.GetKeyDown(KeyCode.C)) { // 如果事件不为空(有订阅者),调用所有订阅此事件的方法。 OnMyEvent?.Invoke(); } } } public class MyEventSubscriber : MonoBehaviour { private void Start() { // 订阅事件 MyEventPublisher.OnMyEvent += HandleMyEvent; } private void OnDisable() { // 取消订阅事件 MyEventPublisher.OnMyEvent -= HandleMyEvent; } private void HandleMyEvent() { Debug.Log("事件被触发"); } } ``` ### 委托事件的优势 使用委托和事件可以有效降低模块之间的耦合度,使得代码更易于维护和扩展。例如,在 UI 按钮点击事件中,使用事件机制可以让多个对象响应同一事件,而不必修改按钮本身的逻辑[^3]。此外,事件机制还能够避免因直接调用方法而可能导致的死循环和逻辑混乱问题[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值