149 lines
3.5 KiB
Markdown
149 lines
3.5 KiB
Markdown
## 疑问
|
||
### 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")
|
||
|
||
|