【Unity】自定义事件实现,管理

本文探讨了如何在Unity中创建自定义事件系统,以增强 MVC 模式的灵活性,解决Unity内建机制的不足。

事件机制广泛应用于mvc模式中,灵活的事件机制能够弥补Unity中的一些缺陷

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

public class EventManager :MonoBehaviour {

    public delegate void Callback();
    public delegate void CallbackPrm(params object[] prm);

    public static EventManager _Event;
    // 最终结束回调字典
    private Dictionary<string, CallbackPrm> _myEventCallback = new Dictionary<string, CallbackPrm>();

    // 最终结束一次回调字典
    private Dictionary<string, CallbackPrm> _myEventOnceCallback = new Dictionary<string, CallbackPrm>();
    
    void Awake()
    {
        _Event = this;
    }
    // Use this for initialization
    void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}

    /// <summary>
    /// 添加事件
    /// </summary>
    /// <param name="name"> 事件名称 </param>
    /// <param name="callback"> 带参事件 </param>
    public void AddEvent(string name, CallbackPrm callback)
    {
        if (_myEventCallback.ContainsKey(name))
        {
            Debug.Log("Events already exist (CallbackPrm)");
        }
        else
        {
            _myEventCallback.Add(name, callback);
        }
    }

    /// <summary>
    /// 添加事件
    /// </summary>
    /// <param name="name"> 动画名称 </param>
    /// <param name="callback"> 不带参事件 </param>
    public void AddEvent(string name, Callback callback)
    {
        if (_myEventCallback.ContainsKey(name))
        {
            Debug.Log("Events already exist (callback)");
        }
        else
        {
            _myEventCallback.Add(name,(object[] o)=> { callback(); });
        }
    }

    /// <summary>
    /// 添加执行一次事件
    /// </summary>
    /// <param name="name"> 事件名称 </param>
    /// <param name="callback"> 带参事件 </param>
    public void AddOnceEvent(string name, CallbackPrm callback)
    {
        if (_myEventOnceCallback.ContainsKey(name))
        {
            Debug.Log("Events already exist (CallbackPrm)");
        }
        else
        {
            _myEventOnceCallback.Add(name, callback);
        }
    }

    /// <summary>
    /// 添加执行一次事件
    /// </summary>
    /// <param name="name"> 动画名称 </param>
    /// <param name="callback"> 不带参事件 </param>
    public void AddOnceEvent(string name, Callback callback)
    {
        if (_myEventOnceCallback.ContainsKey(name))
        {
            Debug.Log("Events already exist (callback)");
        }
        else
        {
            _myEventOnceCallback.Add(name, (object[] o) => { callback(); });
        }
    }

    /// <summary>
    /// 派发事件
    /// </summary>
    /// <param name="name"> 事件名称 </param>
    public void DispatchEvent(string name,params object[] o)
    {
        if (_myEventCallback.ContainsKey(name))
        {
            _myEventCallback[name](o);
        }
        else if (_myEventOnceCallback.ContainsKey(name))
        {
            _myEventOnceCallback[name](o);
            _myEventOnceCallback.Remove(name);
            //Debug.Log("err : 未注册 "+ name);
        }
        else {
            Debug.Log("err : 未注册 " + name);
        }
    }

    /// <summary>
    /// 清理事件
    /// </summary>
    /// <param name="name"> 事件名称 </param>
    public void ClearEvent(string name)
    {
        if (_myEventCallback.ContainsKey(name))
        {
            _myEventCallback.Remove(name);
        }
        if (_myEventOnceCallback.ContainsKey(name))
        {
            _myEventOnceCallback.Remove(name);
        }
    }
}

 

Unity中,可以通过自定义事件系统来实现事件的注册、监听和触发。实现自定义事件系统的核心是创建一个事件管理工具类,用于统一管理事件的添加、移除和派发操作。以下是一个基于C#的实现示例: ### 自定义事件系统实现 创建一个名为 `EventUtil` 的静态类,用于管理事件的监听和触发: ```csharp using System; using System.Collections.Generic; using UnityEngine; public static class EventUtil { // 使用字典存储事件名称与对应的委托列表 private static Dictionary<string, Action<object[]>> eventDictionary = new Dictionary<string, Action<object[]>>(); // 添加事件监听器 public static void AddListener(string eventName, Action<object[]> callback) { if (eventDictionary.TryGetValue(eventName, out var callbacks)) { callbacks += callback; } else { eventDictionary.Add(eventName, callback); } } // 移除事件监听器 public static void RemoveListener(string eventName, Action<object[]> callback) { if (eventDictionary.TryGetValue(eventName, out var callbacks)) { callbacks -= callback; if (callbacks == null) { eventDictionary.Remove(eventName); } else { eventDictionary[eventName] = callbacks; } } } // 派发事件 public static void DispatchEvent(string eventName, params object[] parameters) { if (eventDictionary.TryGetValue(eventName, out var callback)) { callback?.Invoke(parameters); } else { Debug.LogWarning($"No listener for event: {eventName}"); } } } ``` ### 使用自定义事件系统 在具体的Unity脚本中,可以注册监听器并触发事件。例如: ```csharp public class EventTest : MonoBehaviour { void Start() { // 添加事件监听器 EventUtil.AddListener("TestEvent", OnTestEvent); // 触发事件 EventUtil.DispatchEvent("TestEvent", "Hello", 123); } void OnDestroy() { // 移除事件监听器 EventUtil.RemoveListener("TestEvent", OnTestEvent); } // 事件回调方法 private void OnTestEvent(object[] parameters) { foreach (var param in parameters) { Debug.Log($"Received parameter: {param}"); } } } ``` ### 关键点说明 1. **事件管理类**:`EventUtil` 类使用字典来存储事件名称和对应的委托列表,支持动态添加、移除和触发事件。 2. **多参数支持**:通过 `object[]` 参数,事件可以传递多个不同类型的值,提高了灵活性。 3. **内存管理**:在 `OnDestroy` 生命周期中移除事件监听器,可以避免内存泄漏问题。 ### 相关问题 1. 如何在Unity实现跨组件通信的事件系统? 2. Unity自定义事件系统的性能优化方法有哪些? 3. 如何在Unity实现带返回值的事件回调? 4. Unity中如何使用C#委托和事件实现事件驱动架构? 5. 在Unity中使用自定义事件系统时,如何避免重复注册监听器?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值