Files
Obsidian_Unity/项目学习/王国之梦制作/7.泛型事件框架(委托 事件 重难点).md
T
2026-05-03 14:06:26 +08:00

149 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 疑问
### 1.[TextArea]有什么作用?
`[TextArea]` 是一个用于 **增强字符串字段编辑体验** 的重要特性,他的作用是:
- 将普通的单行输入框变为 **可伸缩的多行文本区域**
- 支持 **回车换行** 和 **文本滚动条**
- 默认显示 3 行(可自定义最小/最大行数)
2.BaseEventSO当中为什么不使用UnityEvent而是用UnityAction.
![[Pasted image 20250222185154.png]]
# **过程**
## Unity 事件系统框架解析(广播-监听模式)
## 系统架构图
```markdown
[按钮对象] --广播--> [ObjectEventSO] --通知--> [门对象]
| |
|-- 触发按压动作 |-- 作为事件通道
|-- 连接监听器
```
## 一、核心组件说明
### 1. 广播系统 (EventSO)
#### 1.1 BaseEventSO<T> 基类
```csharp
// 核心功能:管理事件订阅和广播机制
public class BaseEventSO<T> : ScriptableObject
{
[TextArea] // 可视化描述字段
public string description;
// 事件订阅集合(使用object类型保持灵活性)
public UnityAction<T> OnEventRaised;
// 调试信息字段
public string lastSender;
// 事件触发方法
public void RaiseEvent(T value, object sender)
{
OnEventRaised?.Invoke(value);
lastSender = sender.ToString(); // 记录最后发送者
}
}
```
**关键设计:**
- 使用 ScriptableObject 实现全局事件通道
- 泛型设计支持多种参数类型
- lastSender 字段用于调试追踪
#### 1.2 ObjectEventSO 具体实现
```csharp
// 创建菜单项便于生成资产
[CreateAssetMenu(fileName = "ObjectEventSO", menuName = "Event/ObjectEventSO")]
public class ObjectEventSO : BaseEventSO<object> { }
```
**使用场景:**
- 需要传递任意类型参数时
- 通用对象交互场景
- 快速原型开发阶段
### 2. 监听系统 (EventListener)
#### 2.1 BaseEventListener<T> 基类
```csharp
public class BaseEventListener<T> : MonoBehaviour
{
[Header("事件配置")]
public BaseEventSO<T> eventSO; // 绑定的事件资产
[Header("响应事件")]
public UnityEvent<T> response; // 可视化配置的响应事件
private void OnEnable()
{
if(eventSO != null)
eventSO.OnEventRaised += OnEventRaised;
}
private void OnDisable()
{
if(eventSO != null)
eventSO.OnEventRaised -= OnEventRaised;
}
private void OnEventRaised(T value)
{
response.Invoke(value); // 转发事件到UnityEvent
}
}
```
**生命周期管理:**
- OnEnable:注册监听
- OnDisable:注销监听
- 自动化的订阅管理防止内存泄漏
#### 2.2 ObjectEventListener 具体实现
```csharp
public class ObjectEventListener : BaseEventListener<object> { }
```
**扩展说明:**
- 可创建特定类型的监听器(如IntEventListener
- 保持基类的泛型灵活性
## 二、工作流程详解
### 1. 配置阶段
1. 创建 EventSO 资产
- Assets右键 → Create → Event → ObjectEventSO
2. 配置广播者(按钮)
- 添加事件触发脚本
```csharp
public class ButtonPressHandler : MonoBehaviour
{
public ObjectEventSO pressEvent;
void OnMouseDown()
{
pressEvent.RaiseEvent(this, "DoorButton");
}
}
```
3. 配置监听者(门)
- 添加 ObjectEventListener 组件
- 绑定同一个 EventSO 资产
- 配置 Response 事件链(示例):
- 添加 GameObject.SetActive(false)
- 添加 Animator.Play("OpenDoor")