赞
踩
当在Unity中应用观察者模式时,通常是为了实现一种解耦和灵活性较强的事件机制。观察者模式允许一个对象(称为主题)维护一组依赖于它的对象(称为观察者),当主题的状态发生变化时,所有观察者都能够得到通知并进行相应的处理。
总体而言,观察者模式在Unity中的应用能够提高代码的灵活性、可维护性和可扩展性,是一种强大的设计模式。
观察者模式在Unity当中的适用场景有很多,下面主要介绍的是事件管理器的应用,直接上代码。
- using Mr.Le.Utility.Singleton;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Events;
-
- namespace Mr.Le.Utility.Manager
- {
- /// <summary>
- /// 事件管理器
- /// </summary>
- public class EventCenterManager : NoMonoSingleton<EventCenterManager>
- {
- /// <summary>
- /// 用于里氏替换的接口
- /// </summary>
- private interface IEventInfo
- {
-
- }
-
- //事件集合
- private Dictionary<string, IEventInfo> _events = new Dictionary<string, IEventInfo>();
-
-
- #region 无参事件
-
- private class EventInfo : IEventInfo
- {
- public UnityAction action;
-
- /// <summary>
- /// 构造函数添加事件
- /// </summary>
- /// <param name="call"></param>
- public EventInfo(UnityAction call)
- {
- action += call;
- }
- }
-
- /// <summary>
- /// 添加事件监听
- /// </summary>
- /// <param name="command"></param>
- /// <param name="call"></param>
- public void AddEventListener(object command, UnityAction call)
- {
- string name = command.GetType().Name + "_" + command;
-
- if (_events.ContainsKey(name))
- {
- (_events[name] as EventInfo).action += call;
- }
- else
- {
- _events.Add(name, new EventInfo(call));
- }
- }
-
- /// <summary>
- /// 移除指定事件的指定监听
- /// </summary>
- /// <param name="command"></param>
- /// <param name="call"></param>
- public void RemoveEventListener(object command, UnityAction call)
- {
- string name = command.GetType().Name + "_" + command;
- if (_events.ContainsKey(name))
- {
- (_events[name] as EventInfo).action -= call;
- }
- else
- {
- Debug.LogError($"{name}事件不存在!");
- return;
- }
- }
-
- /// <summary>
- /// 移除指定事件的所有监听
- /// </summary>
- /// <param name="command"></param>
- public void RemoveAllEventListeners(object command)
- {
- string name = command.GetType().Name + "_" + command;
-
- if (_events.ContainsKey(name))
- {
- (_events[name] as EventInfo).action = null;
- }
- else
- {
- Debug.LogError($"{name}事件不存在!");
- return;
- }
- }
-
- /// <summary>
- /// 呼叫事件
- /// </summary>
- /// <param name="command"></param>
- public void CallEvent(object command)
- {
- string name = command.GetType().Name + "_" + command;
- if (_events.ContainsKey(name))
- {
- (_events[name] as EventInfo).action?.Invoke();
- }
- else
- {
- Debug.LogError($"{name}事件不存在!");
- return;
- }
- }
-
- #endregion
-
- #region 有参事件
-
- private class EventInfo<T> : IEventInfo
- {
- public UnityAction<T> action;
-
- /// <summary>
- /// 构造函数添加事件
- /// </summary>
- /// <param name="call"></param>
- public EventInfo(UnityAction<T> call)
- {
- action += call;
- }
- }
-
- /// <summary>
- /// 添加事件监听
- /// </summary>
- /// <param name="command"></param>
- /// <param name="call"></param>
- public void AddEventListener<T>(object command, UnityAction<T> call)
- {
- string name = command.GetType().Name + "_" + command;
-
- if (_events.ContainsKey(name))
- {
- (_events[name] as EventInfo<T>).action += call;
- }
- else
- {
- _events.Add(name, new EventInfo<T>(call));
- }
- }
-
- /// <summary>
- /// 移除指定事件的指定监听
- /// </summary>
- /// <param name="command"></param>
- /// <param name="call"></param>
- public void RemoveEventListener<T>(object command, UnityAction<T> call)
- {
- string name = command.GetType().Name + "_" + command;
- if (_events.ContainsKey(name))
- {
- (_events[name] as EventInfo<T>).action -= call;
- }
- else
- {
- Debug.LogError($"{name}事件不存在!");
- return;
- }
- }
-
- /// <summary>
- /// 移除指定事件的所有监听
- /// </summary>
- /// <param name="command"></param>
- public void RemoveAllEventListeners<T>(object command)
- {
- string name = command.GetType().Name + "_" + command;
-
- if (_events.ContainsKey(name))
- {
- (_events[name] as EventInfo<T>).action = null;
- }
- else
- {
- Debug.LogError($"{name}事件不存在!");
- return;
- }
- }
-
- /// <summary>
- /// 呼叫事件
- /// </summary>
- /// <param name="command"></param>
- public void CallEvent<T>(object command, T value)
- {
- string name = command.GetType().Name + "_" + command;
- if (_events.ContainsKey(name))
- {
- (_events[name] as EventInfo<T>).action?.Invoke(value);
- }
- else
- {
- Debug.LogError($"{name}事件不存在!");
- return;
- }
- }
-
- #endregion
- }
- }
被观察类:
- public class Observer : MonoBehaviour
- {
- private void OnEnable()
- {
- EventCenterManager.Instance.AddEventListener("事件1", TestFunc);
- }
-
- private void OnDisable()
- {
- EventCenterManager.Instance.RemoveEventListener("事件1", TestFunc);
- }
-
- private void TestFunc()
- {
- Debug.Log("这是一个无参事件的测试方法");
- }
- }
调用事件:
- public class Player : MonoBehaviour
- {
- // Start is called before the first frame update
- void Start()
- {
- EventCenterManager.Instance.CallEvent("事件1");
- }
-
- // Update is called once per frame
- void Update()
- {
-
- }
- }
被观察者类
- public class Observer : MonoBehaviour
- {
- private void OnEnable()
- {
- EventCenterManager.Instance.AddEventListener<bool>("事件2", TestFunc);
- }
-
- private void OnDisable()
- {
- EventCenterManager.Instance.RemoveEventListener<bool>("事件2", TestFunc);
- }
-
- private void TestFunc(bool value)
- {
- if (value)
- Debug.Log("这是一个真消息!");
- else
- Debug.Log("这是一个假消息!");
- }
- }
调用事件:
- public class Player : MonoBehaviour
- {
- // Start is called before the first frame update
- void Start()
- {
- EventCenterManager.Instance.CallEvent("事件2",true);
- }
-
- // Update is called once per frame
- void Update()
- {
-
- }
- }
通过以上示例,你可以更好地理解在Unity中如何使用观察者模式来实现一种灵活且可维护的设计。
希望这篇文章对你理解和应用观察者模式有所帮助。如果有任何疑问或建议,请在评论区留言。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。