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")
|
|||
|
|
|
|||
|
|
|