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

目录

前言:

一、定义事件基础类

二、定义事件资源类

三、定义事件管理类

四、事件使用实例


前言:

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

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

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

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

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


 

一、定义事件基础类


    public  class UEvent
    {

        public readonly int type;

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

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

 

二、定义事件资源类

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

TriggerEvent 触发相应事件

订阅Subscribe相应事件

取消订阅Unsubscribe相应事件

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

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

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

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

        }

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

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

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

三、定义事件管理类

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

订阅事件接口

        public void Subscribe(int type, Action<UEvent> handler)

取消订阅接口

public  void Unsubscribe(int type, Action<UEvent> 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<int> firingTypes = new HashSet<int>();
        private readonly UEventSource<UEvent> source = new UEventSource<UEvent>();
        private readonly List<UEvent> tickEvents = new List<UEvent>();

        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<UEvent> handler)
        {

            source.Subscribe(type, handler);
        }


        public  void Unsubscribe(int type, Action<UEvent> 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;

    }

定义死亡事件

    /// <summary>
    /// 死亡事件
    /// </summary>
    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,如果是,那么就胜利了

 


  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity实现 MVC 架构通常需要以下几步: 1. 创建 Model 类:Model 类用于存储数据和数据操作方法,例如: ``` public class PlayerModel { private int _health; public int Health { get { return _health; } set { _health = value; if (_health <= 0) { // 触发死亡事件 OnDeath(); } } } public event Action OnDeath; public void TakeDamage(int amount) { Health -= amount; } } ``` 2. 创建 View 类:View 类用于显示数据,例如: ``` public class PlayerView : MonoBehaviour { public TextMeshProUGUI healthText; public void UpdateHealth(int health) { healthText.text = "Health: " + health; } } ``` 3. 创建 Controller 类:Controller 类用于控制 Model 和 View,例如: ``` public class PlayerController { private PlayerModel _model; private PlayerView _view; public PlayerController(PlayerModel model, PlayerView view) { _model = model; _view = view; // 监听 Model 的数据变化并更新 View _model.OnHealthChanged += _view.UpdateHealth; // 监听 View 的用户操作并控制 Model _view.OnTakeDamage += _model.TakeDamage; } } ``` 4. 在场景中创建 View 对象,并在 Controller 中传入 Model 和 View: ``` public class GameController : MonoBehaviour { public PlayerView playerViewPrefab; private void Start() { // 创建 Model 对象 var playerModel = new PlayerModel(); // 创建 View 对象并绑定到场景中的 GameObject 上 var playerView = Instantiate(playerViewPrefab); playerView.transform.SetParent(transform, false); // 创建 Controller 对象并传入 Model 和 View var playerController = new PlayerController(playerModel, playerView); } } ``` 这样就完成了一个简单的 MVC 架构实现。在实际项目中,可能需要更复杂的 Model 和 View 类,以及更多的 Controller 类来控制不同的数据和视图。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值