unity前端架构之事件系统完整代码实现

目录

前言:

一、定义事件基础类

二、定义事件资源类

三、定义事件管理类

四、事件使用实例


前言:

在Unity游戏开发中,事件系统非常重要,主要原因有以下几点:

  1. 松耦合:通过事件系统,我们可以实现代码的松耦合,这意味着我们可以将代码中的类解耦。在游戏开发中,如果代码是紧耦合的,当代码量增大时,很容易导致代码混乱难以维护。事件系统的松耦合可以减小这种压力,可以更好地组合和管理游戏对象。

  2. 效率高:使用事件系统可以让游戏对象通过广播自己的状态,而不需要每个游戏对象都去检测其他对象的状态,这可以对性能产生显着影响,从而提高游戏效率。

  3. 易扩展:当游戏需要新的功能时,通过事件系统,我们可以很容易地扩展代码,只需创造新的事件,并让其他代码订阅新事件即可,而不必改变原有代码。

总之,使用事件系统可以帮助我们设计和管理游戏对象,增加代码的可读性和可维护性,同时也可以提高游戏运行效率和可扩展性。在Unity游戏开发中,事件系统可以说是不可或缺的一部分。


 

一、定义事件基础类


    public  class UEvent
    {

        public readonly int type;

        public UEvent(int eventType)
        {
            this.type = eventType;
        }

        public static T New() where T: UEvent, IPoolItem,new()
        {
            return Engine.Pools.Pop();
        }
    }

 

二、定义事件资源类

事件资源类是真正处理事件的内部类,它有三个重要的接口

TriggerEvent 触发相应事件

订阅Subscribe相应事件

取消订阅Unsubscribe相应事件

using System;
using System.Collections.Generic;
 
internal class UEventSource where T : UEvent
    {
        private readonly Dictionary>> events = new Dictionary>>();

        internal void TriggerEvent(T value)
        {
            var key = value.type;

            if (!events.TryGetValue(key, out List> outList))
                return;

            for (var i = 0; i < outList.Count; i++)
            {
                outList[i]?.Invoke(value);
            }

        }

        internal void Subscribe(int type, Action handler)
        {
            if (events.ContainsKey(type))
            {
                List> list = events[type];
                if (list == null)
                {
                    list = new List>();
                    events[type] = list;
                }
#if UNITY_EDITOR
                if (list.Contains(handler))
                {
                    ULog.Warn("重复注册事件 {0} {1}", type, handler);
                    return;
                }
#endif
                list.Add(handler);
            }
            else
            {
                List> list = new List> {handler};
                events[type] = list;
            }
        }

        internal void Unsubscribe(int type, Action handler)
        {
            if (events.ContainsKey(type))
            {
                List> list = events[type];
                if (list != null)
                {
                    list.Remove(handler);
                }
            }
        }

        internal void Destroy()
        {
            events.Clear();
        }

三、定义事件管理类

事件管理类是对外操作类,它提供了异步触发和立即触发功能,包含总要的几个接口:

订阅事件接口

        public void Subscribe(int type, Action handler)

取消订阅接口

public  void Unsubscribe(int type, Action handler)

 立即触发接口

private void TriggerEventImmediate(UEvent value)

 发送事件

public  void SendMessage(UEvent value, bool isImmediate=true)

isImmediate表示是否立刻触发,否则等下帧触发 

 事件管理类完整代码

using System;
using System.Collections.Generic;
 public class EventsComponent
    {
        private readonly HashSet firingTypes = new HashSet();
        private readonly UEventSource source = new UEventSource();
        private readonly List tickEvents = new List();

        public  void SendMessage(UEvent value, bool isImmediate=true)
        {

            if (isImmediate)
            {
                TriggerEventImmediate(value);
                return;
            }
            tickEvents.Add(value);

        }

        public void Update()
        {
            if (tickEvents.Count == 0)
                return;

            foreach (var t in tickEvents)
            {
                TriggerEventImmediate(t);
            }

            tickEvents.Clear();
  
        }

        public void Subscribe(int type, Action handler)
        {

            source.Subscribe(type, handler);
        }


        public  void Unsubscribe(int type, Action handler)
        {
            source.Unsubscribe(type, handler);
        }

        public void Destroy()
        {            
            tickEvents.Clear();
            firingTypes.Clear();
            source.Destroy();
        }

        private void TriggerEventImmediate(UEvent value)
        {
            firingTypes.Add(value.type);
            source.TriggerEvent(value);
            firingTypes.Remove(value.type);
        }
    }

 

四、事件使用实例

在一个关卡中,游戏角色死亡作为我们判定结果的一个唯一条件,我们希望该角色死亡就触发结果,就以此为例写一个简单实例。

定义事件类型

    public class EventLogicCode
    {

        public  const int Dead           = 1;

    }

定义死亡事件

    /// 
    /// 死亡事件
    /// 
    public class EventDead : UEvent
    {
        public int _actorId;

        public EventDead() : base(EventLogicCode.Dead)
        {
        }

    }

角色类代码如下

public class Charactor
{
  
    private EventsComponent _events;    //记得给事件组件赋值
    private int _id;
    ....
    //角色死亡调用
    public void Dead()
    {
        EventDead  dead = new EventDead();
        dead.id = id;
        _events?.SendMesage(dead);
    }
}

结果控制类

public class ResultController : MonoBehaviour
{
    private EventsComponent _events;//记得赋值
    private int _winId;
    .....
     private void OnEnable()
    {
            _events?.Subscribe(EventLogicCode.Dead, BeginFade);
    }

    private void OnDisable()
    {
         _events?.Unsubscribe(EventLogicCode.Dead, BeginFade);
    }
    public void OnDead(UEvent e)
    {
        EventDead dead = e as EventDead;
        if(dead.id == _winId)
        {
            GameWin();
        }
    }

    private void GameWin()
    {
        ....
    }
}

 该类描述的是当角色死亡时判定是不是与胜利条件相同的Id,如果是,那么就胜利了

 


你可能感兴趣的:(unity,开发语言,unity,游戏引擎,架构)