当前位置: 首页 > news >正文

Unity笔记——事件中心

事件中心是什么

事件中心是 Unity 游戏开发中常用的架构设计,它基于观察者模式 或 发布-订阅模式,通过委托事件构建的一种消息管理系统。主要用于降低代码耦合度,实现模块间的松耦合通信的消息处理系统能大幅提升代码的可维护性和扩展性,允许不同脚本在不直接引用彼此的情况下进行交互。

作用

1. 解耦代码,减少直接依赖

传统方式:A 脚本调用 B 脚本的方法,需要 GetComponent<B>() 或持有 B 的引用。

事件中心方式:A 触发事件,B 监听事件,两者无需互相知道对方存在。

2. 全局通信

任何脚本都可以监听或触发事件,适合跨场景、跨系统的通信(如UI更新、游戏状态变化、敌人死亡通知等)。

3. 动态管理事件

可以随时添加/移除事件监听,避免硬编码调用关系。

适合动态场景(如玩家死亡后取消某些监听)。

4. 支持多参数传递

事件可以携带数据(如 int damage、string playerName、Vector3 position 等)。

应用场景

1. 游戏逻辑(如敌人死亡、任务完成)

2. UI交互(如按钮点击、数据更新)

3. 场景切换(如清理事件缓存)

实现方式

EventCenter 代码可直接食用,无需挂载在场景中,可供全局使用。

该消息中心设置了一个不限返回数据类型的委托    params object[] msg;

同时将消息名和对应的回调方法以键值对的方式存储在字典中    Dictionary<string, EventHandler>;

消息中心除了在触发相应事件的时候调用相应的回调函数,还能传回不同类型、数量的数据。

using UnityEngine;
using System.Collections.Generic;public static class EventCenter
{// 事件委托定义,用于回调函数,参数为object数组,返回值为空public delegate void EventHandler(params object[] msg);// 消息字典private static Dictionary<string, EventHandler> messageDic = new Dictionary<string, EventHandler>();// 注册消息监听public static void AddListener(string msgName, EventHandler eventHandler){if (messageDic.ContainsKey(msgName)){messageDic[msgName] += eventHandler;}else{messageDic.Add(msgName, eventHandler);}}// 注销消息监听public static void RemoveListener(string msgName, EventHandler eventHandler){if (messageDic.ContainsKey(msgName)){messageDic[msgName] -= eventHandler;if (messageDic[msgName] == null){messageDic.Remove(msgName);}}}// 触发消息public static void TriggerEvent(string msgName, params object[] msg){if (messageDic.TryGetValue(msgName, out EventHandler eventHandler)){eventHandler.Invoke(msg);}else{Debug.Log("消息" + msgName + "未注册");}}// 清空所有消息监听public static void Clear(){messageDic.Clear();}
}

 使用方法

先注册消息,开始监听事件。根据需求注销消息,取消监听事件。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class GameManager: MonoBehaviour
{private void Start(){// 注册消息EventCenter.AddListener("startGame", StartGame);}private void OnDestroy(){// 注销消息EventCenter.RemoveListener("startGame", StartGame);}// 被监听的事件所对应的方法需要有一个与委托对应的参数类型  object[] args = nullpublic void StartGame(object[] args = null){if (args != null){foreach (var arg in args){Debug.Log(arg);}}Debug.Log("Start Game");}
}

触发消息,触发监听事件。同时,下面设置了三个用例,在触发回调函数的同时还传回相关参数。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Test: MonoBehaviour
{private void Update(){if (Input.GetKeyDown(KeyCode.J)){Test1();}if (Input.GetKeyDown(KeyCode.K)){Test2();}if (Input.GetKeyDown(KeyCode.L)){Test3();}}void Test1(){// 触发消息EventCenter.TriggerEvent("startGame");}void Test2(){// 触发消息EventCenter.TriggerEvent("startGame", 1);}void Test3(){// 触发消息EventCenter.TriggerEvent("startGame", 1, "test");}
}

 

http://www.lryc.cn/news/596401.html

相关文章:

  • HTB赛季8靶场 - Mirage
  • 风险识别清单:构建动态化的风险管理体系
  • Java函数式编程深度解析:从基础到高阶应用
  • 技能系统详解(4)——运动表现
  • 哔哩哔哩视觉算法面试30问全景精解
  • 钢铁逆行者:Deepoc具身智能如何重塑消防机器人的“火场直觉”
  • 【中文翻译】SmolVLA:面向低成本高效机器人的视觉-语言-动作模型
  • Vue 3 响应式系统中的 effectScope、watchEffect、effect 和 watch 详解
  • 如何将iPad中的视频传输到电脑(6种简单方法)
  • 单片机学习笔记.单总线one-wire协议(这里以普中开发板DS18B20为例)
  • rabbitmq 03
  • uniapp 报错 Not found ... at view.umd.min.js:1的问题
  • LWIP学习记录2——MAC内核
  • Linux系统安装Bash自动补全(bash-completion)
  • 基于SpringBoot+Uniapp的非遗文化宣传小程序(AI问答、协同过滤算法、Echarts图形化分析)
  • uniapp请求封装上传
  • 最新植物大战僵尸杂交版最新版本2.5.1版,内置触屏+加速+全屏,附PC+安卓+iOS最全安装教程!
  • C#文件操作(创建、读取、修改)
  • Java学习-------事务失效
  • 从“点状用例”到“质量生态”:现代软件测试的演进、困局与破局
  • Vue3 学习教程,从入门到精通,Vue3 循环语句(`v-for`)语法知识点与案例详解(13)
  • C# 属性
  • XSS(跨站脚本)
  • CPU 密集型 和 I/O 密集型 任务
  • 达梦数据库表字段增加时报错[-2106]:无效的表或视图名,[-2116]:列[IS_REPEAT]已存在
  • 【C++】第十八节—一文万字详解 | map和set的使用
  • 如何搭建appium工具环境?
  • Go的异常处理+文件处理
  • JAVA API (三):从基础爬虫构建到带条件数据提取 —— 详解 URL、正则与爬取策略
  • M3088NL是一款网络滤波器/变压器支持100M和1000M网络环境,适用于高速网络传输场景M3088