Unity设计模式之观察者模式

文章介绍了如何在Unity游戏开发中使用观察者模式来降低耦合性,通过事件中心管理类统一调度各个对象的方法调用。例如,当勇者杀死怪物时,通过事件触发,使得玩家摆出胜利姿势,同时提示框显示相应信息。观察者模式简化了对象之间的交互,使得代码更加模块化。
摘要由CSDN通过智能技术生成

  在平常玩游戏的时候会遇到这种情况,以简单的Rpg举例。 勇者击杀了怪物,怪物死了,勇者摆出胜利姿势,系统提示怪物死亡 。如果按照一般逻辑可能会在怪物死亡的方法中去获取Player、Dialog,这样看上去其实也不太难。但如果需要去关联的事件很多,就需要在类中去获取各种各样的对象,非常麻烦而且也会使程序耦合性变高,这时就需要使用到观察者模式。

  观察者模式其本质就是通过委托将各个类中的方法都关联到一个固定的类上去,由该管理类去统一决定是否调用。由于很像是管理类去观察着各个类的情况,所以我们管这种设计模式叫做观察者模式,下面是观察者模式的简单实现。

  首先我们假定有三个对象分别是勇者(Player)、怪物(Monster)、提示框(Dialog)

 

public class Dialog : MonoBehaviour
{
    private void DialogSay(object info) {
        Debug.Log("叮咚!怪物已经寄了!");
    }
}

public class Player : MonoBehaviour
{
    
    private void Victor(object info) {
        Debug.Log("玩家摆出胜利姿势");
    }      
}
public class Monster : MonoBehaviour
{
    
    private void Start()
    {
        Dead();
    }
}

其中各自的类有各自的方法,完成不同的事情。

接下来使用统一的管理类起个名字叫做事件中心,代码如下

public class EventCenter : ISingleton
    {
        public static EventCenter Instance => Singleton<EventCenter>.Instace;

        /// <summary>
        /// 事件容器
        /// </summary>
        private Dictionary<string,UnityAction<object>> eventDic=new Dictionary<string, UnityAction<object>>();
        public void Init()
        {

        }

        /// <summary>
        /// 添加事件监听
        /// </summary>
        /// <param name="name">事件名字</param>
        /// <param name="action">准备用来处理事件的委托函数</param>
        public void AddEventListener(string name ,UnityAction<object> action) {
            if (eventDic.ContainsKey(name))
            {
                eventDic[name] += action;
            }
            else
            {
                eventDic.Add(name, action);
            }
        }

        /// <summary>
        /// 事件触发
        /// </summary>
        /// <param name="name"></param>
        public void EventTrigger(string name,object info) {
            if (eventDic.ContainsKey(name))
            {
                eventDic[name].Invoke(info);
            }
        }

        /// <summary>
        /// 移除事件监听
        /// </summary>
        /// <param name="name">事件名字</param>
        /// <param name="action">委托函数</param>
        public void RemoveEventListener(string name,UnityAction<object> action) {
            if (eventDic.ContainsKey(name))
                eventDic[name]-=action;        
        }

        /// <summary>
        /// 清空事件中心
        /// </summary>
        public void Clear() { 
            eventDic.Clear();
        }
    }

事件中心里,首先是有一个Dict事件容器Dictionary<string,UnityAction<object>>,用于存放各类事件,字典的键是事件的名字、值该事件委托。然后为了能够使在挂载事件的时候也能进行参数的传递,使用了泛型委托。然后中心对外提供四个方法,添加事件 AddEventListener、移除事件RemoveEventListener、事件触发器EventTrigge以及清空事件Clear。整个程序流程基本是,发生了某件事情,然后事件中心告知各个类对这个事件的响应。所以需要让各个类与事件中心关联起来。代码入下

    public class Player : MonoBehaviour
{
    private void Start()
    {
        EventCenter.Instance.AddEventListener("MonsterDie", Victor);
    }
    private void Victor(object info) {
        if (diedMonsterType == 1)
        {
            Debug.Log("死的是史莱姆");
        }
        Debug.Log("玩家摆出胜利姿势");
    }

    private void OnDestroy()
    {
        EventCenter.Instance.RemoveEventListener("MonsterDie", Victor);
    }             
}
    public class Dialog : MonoBehaviour
{
    private void Start()
    {
        EventCenter.Instance.AddEventListener("MonsterDie", DialogSay);
    }

    private void DialogSay(object info) {
        Debug.Log("叮咚!怪物已经寄了!");
    }
}
    public class Monster : MonoBehaviour
{
    /// <summary>
    /// 怪物类型(转发事件时参数的传递)
    /// </summary>
    public int monsterType = 1;
    private void Start()
    {
        Dead();
    }

    public void Dead()
    {
        Debug.Log("怪物已经死了");
        EventCenter.Instance.EventTrigger("MonsterDie",this.monsterType);
    }

}

当Monster被挂载到游戏对象上,游戏运行Start函数被调用,执行Dead方法,打印出“怪物已经死了”,然后事件中心触发名为“MonsterDie”事件并传入monsterType怪物类型,事件中心根据字典中的委托调用各个应该响应类中的函数。并且将monsterType作为参数传递到各个函数中,让响应类能够针对type不同做出判断,最终打印。

 以上就是观察者模式的简单实现。

Unity中的观察者模式是一种设计模式,用于实现对象之间的一对多依赖关系。它允许一个被观察的对象(称为主题或被观察者)维护一组依赖于它的对象列表(称为观察者),并在状态发生变化时自动通知观察者。 在Unity中,可以使用C#语言和相关的Unity API来实现观察者模式。下面是一个简单的示例: ```csharp // 定义观察者接口 public interface IObserver { void OnNotify(); } // 定义被观察者类 public class Subject { private List<IObserver> observers = new List<IObserver>(); public void AddObserver(IObserver observer) { observers.Add(observer); } public void RemoveObserver(IObserver observer) { observers.Remove(observer); } public void NotifyObservers() { foreach (var observer in observers) { observer.OnNotify(); } } } // 实现观察者类 public class Observer : IObserver { public void OnNotify() { // 处理通知的逻辑 } } // 使用观察者模式 public class Example : MonoBehaviour { private Subject subject = new Subject(); private Observer observer = new Observer(); private void Start() { subject.AddObserver(observer); } private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { subject.NotifyObservers(); } } } ``` 在上面的示例中,Subject类是被观察者,它维护了一个观察者列表。Observer类是观察者,它实现了IObserver接口的OnNotify方法来处理通知的逻辑。Example类演示了如何使用观察者模式,在Start方法中将观察者添加到被观察者的列表中,在Update方法中按下空格键时通知观察者。 这只是一个简单的例子,实际应用中可能会有更复杂的场景和逻辑。观察者模式Unity中的应用广泛,可以用于处理事件、消息传递、UI更新等各种情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值