Unity中,C#的事件与委托区别和经典实例

文章目录

在Unity中,C#的事件处理与委托密切相关。下面通过5个实例来详细阐述它们的区别和使用场景:

实例1:委托(Delegate)的基本用法

csharp 复制代码
public delegate void MyAction(string message);

public class MyClass
{
    private MyAction _myAction;

    public MyClass(MyAction action)
    {
        _myAction = action;
    }

    public void TriggerAction()
    {
        if (_myAction != null)
            _myAction("触发了一个动作!");
    }
}

public class MainScript : MonoBehaviour
{
    void Start()
    {
        MyClass myClass = new MyClass(OnActionTriggered);
    }

    void OnActionTriggered(string message)
    {
        Debug.Log(message);
    }
}

在这个例子中,MyAction 是一个自定义的委托类型,它引用了一个无返回值并接受字符串参数的方法。当 MyClass 中的 TriggerAction 方法被调用时,会执行传递给构造函数的委托方法 OnActionTriggered。

实例2:事件(Event)的声明与订阅

csharp 复制代码
public class EventExample : MonoBehaviour
{
    // 声明一个基于委托类型的事件
    public event Action<string> OnMessageReceived;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 触发事件
            OnMessageReceived?.Invoke("接收到一个消息!");
        }
    }

    void OnEnable()
    {
        // 订阅事件
        OnMessageReceived += HandleMessage;
    }

    void OnDisable()
    {
        // 取消订阅事件
        OnMessageReceived -= HandleMessage;
    }

    void HandleMessage(string message)
    {
        Debug.Log(message);
    }
}

在此例中,我们定义了一个名为 OnMessageReceived 的事件,它是基于 Action<string> 委托的。通过 += 和 -= 运算符可以添加或移除事件的监听器(即响应事件的方法)。当按下空格键时,事件会被触发,并通知所有已订阅的监听器。

实例3:Unity引擎中的委托实例 - UI Button.onClick

csharp 复制代码
public class UIExample : MonoBehaviour
{
    public Button myButton;

    void Start()
    {
        // 将方法赋值给按钮点击事件的委托
        myButton.onClick.AddListener(ButtonClicked);
    }

    void ButtonClicked()
    {
        Debug.Log("按钮被点击了!");
    }

    void OnDestroy()
    {
        // 清理事件监听器以防止内存泄漏
        myButton.onClick.RemoveAllListeners();
    }
}

这个实例展示了Unity引擎内置的UI组件Button中对委托的实际应用。onClick 是一个预定义的 UnityEvent,它背后也是基于委托机制实现的。这里我们为按钮点击事件添加了一个监听器方法 ButtonClicked。

实例4:事件(Event)的安全性

csharp 复制代码
public class SafeEventExample
{
    // 私有存储事件的委托实例
    private event EventHandler<MyEventArgs> SafeEvent;

    public void RaiseSafeEvent(string data)
    {
        SafeEvent?.Invoke(this, new MyEventArgs(data));
    }

    public void Subscribe(EventHandler<MyEventArgs> handler)
    {
        SafeEvent += handler;
    }

    public void Unsubscribe(EventHandler<MyEventArgs> handler)
    {
        SafeEvent -= handler;
    }

    public class MyEventArgs : EventArgs
    {
        public readonly string Data;

        public MyEventArgs(string data)
        {
            Data = data;
        }
    }
}

此例强调了事件相对于直接操作委托的安全性。事件通常在类内部作为一个私有字段进行封装,并提供公共的 += 和 -= 方法来管理订阅者。这样可以防止外部代码随意修改或触发事件。

实例5:事件处理器链(Multicast Delegate)

csharp 复制代码
public class MulticastDelegateExample
{
    public delegate void MessageHandler(string message);

    public event MessageHandler OnMessage;

    void Awake()
    {
        OnMessage += PrintToConsole;
        OnMessage += SendEmail;

        // 触发事件,多个监听器将依次执行
        OnMessage("多重委托示例");
    }

    void PrintToConsole(string message)
    {
        Debug.Log("打印到控制台:" + message);
    }

    void SendEmail(string message)
    {
        Debug.Log("模拟发送邮件:" + message);
    }
}

在这个实例中,单个事件可以关联多个不同的方法,这就是多播委托的概念。当事件触发时,所有的注册方法(如 PrintToConsole 和 SendEmail)都会按顺序执行。这是事件功能的一个重要特性,允许单一事件触发多个相关的行为。

总结:

  • 委托是类型安全的函数指针,用于表示可重用的方法签名。
  • 事件是一种设计模式,它基于委托机制,提供了发布/订阅模型,确保了安全性(不可直接调用或修改),且支持多播(多个方法可以同时响应同一个事件)。
  • 在Unity中,事件通常用于游戏对象间的通信,例如用户输入、状态变化或其他特定游戏逻辑的通知。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)


​最后我们放松一下眼睛

相关推荐
进击的大海贼14 小时前
基于C#开发的久坐提醒工具
开发语言·c#
小羊没烦恼!16 小时前
关于大型asp.net应用系统的架构-架构的选择
java·服务器·开发语言·前端·c#
小羊没烦恼!1 天前
系统内部模块(子系统)之间的耦合以及模块(子系统)划分
java·开发语言·前端·数据库·算法·c#
UIU1142 天前
头文件可以防什么错?运用头文件做声明
c++·学习·c#
鑫 源2 天前
C#源码开源, 获取macOS 电池数据,包括iOS (xamarin开发)
c#·.net·xamarin
爱吃奥利奥_wen2 天前
面向对象三板斧:封装、继承、多态,到底在“装“什么、“承“什么、“变“什么?
开发语言·经验分享·c#
辻弋2012 天前
五年前的旅行视频糊成马赛克?Video2X用Real-ESRGAN逐帧重建细节,但只支持Windows、集显用户建议直接放弃
服务器·数据库·windows·游戏引擎·电脑
Martina_03213 天前
AI生成3D场景导入 Unity/Unreal 后,NPC 总串层?用6步检查导航高度与跨层连接
人工智能·游戏·数学建模·3d·unity·自然语言处理·aigc
wflynn3 天前
GitHub 今日推荐|SCSKiller:游戏着色器预编译消除卡顿
开源·c#·github·nvidia·amd·directx12