115 lines
5.7 KiB
Markdown
115 lines
5.7 KiB
Markdown
---
|
||
title: "Unity Architect Agent Personality"
|
||
type: source
|
||
tags: [unity, game-engineering, architecture, scriptableobjects, design-patterns]
|
||
date: 2026-05-02
|
||
---
|
||
|
||
## Source File
|
||
- [[Agent/agency-agents/game-development/unity/unity-architect.md]]
|
||
|
||
## Summary(用中文描述)
|
||
- 核心主题:Unity 游戏架构中的数据驱动、模块化设计方法论,基于 ScriptableObject 构建可扩展系统
|
||
- 问题域:Unity 项目中常见的代码耦合、单体类蔓延、硬编码引用等架构腐败问题
|
||
- 方法/机制:ScriptableObject First Design + 单职责组件模式 + SO 事件通道 + RuntimeSet 追踪
|
||
- 结论/价值:消除 GameObject 中心主义,通过 SO 资产实现设计师友好、可测试、易扩展的架构
|
||
|
||
## Key Claims(用中文描述)
|
||
- 所有共享游戏数据必须存于 ScriptableObject,不得通过 MonoBehaviour 字段跨场景传递
|
||
- 每个 MonoBehaviour 只解决一个问题,超过 150 行几乎必然违反 SRP
|
||
- 跨系统通信必须通过 SO 事件通道,禁止 `GameObject.Find()`、`FindObjectOfType()`、静态单例
|
||
- Prefab 必须完全自包含,放入空场景无错误;序列化脚本修改必须调用 `EditorUtility.SetDirty()`
|
||
|
||
## Key Quotes
|
||
> "Eliminate hard references between systems using ScriptableObject event channels" — SO 事件通道替代硬引用
|
||
> "Every prefab dragged into a scene must be fully self-contained — no assumptions about scene hierarchy" — Prefab 自包含原则
|
||
> "If a class exceeds ~150 lines, it is almost certainly violating SRP" — 代码行数红线
|
||
|
||
## Key Concepts
|
||
- [[ScriptableObject]]:Unity 资产,可存储数据无需挂载到 GameObject,用于变量、事件、运行时集合
|
||
- [[Single Responsibility Principle]]:每个 MonoBehaviour 仅负责一个职责,超长组件必须拆分
|
||
- [[Event Channel Pattern]]:SO 事件通道(GameEvent)实现跨系统解耦通信
|
||
- [[RuntimeSet]]:ScriptableObject 管理的实体运行时集合,无单例开销
|
||
- [[Addressables]]:Unity 资源管理系统,替代 Resources.Load,支持细粒度内存控制和 DLC
|
||
- [[DOTS (Data-Oriented Tech Stack)]]:Unity ECS,Job System + Burst Compiler 优化性能关键路径
|
||
- [[Burst Compiler]]:将 C# Job 代码编译为近乎原生性能的机器码
|
||
- [[Data-Oriented Design]]:面向数据的设计,与面向对象互补,提升 CPU 缓存命中率
|
||
|
||
## Key Entities
|
||
- **UnityArchitect**:角色名,资深 Unity 工程师,数据驱动模块化设计专家,拒绝 GameObject 中心主义
|
||
- **FloatVariable**:SO 变量资产示例,支持运行时值变更事件
|
||
- **GameEvent**:SO 事件通道资产,用于跨 MonoBehaviour 解耦通信
|
||
- **RuntimeSetRegistrar**:MonoBehaviour,在 OnEnable/OnDisable 时向 RuntimeSet 注册/注销
|
||
|
||
## Connections
|
||
- [[Unity Multiplayer Engineer]] ← extends ← [[Unity Architect]](多人网络扩展基础架构)
|
||
- [[Unity Shader Graph Artist]] ← extends ← [[Unity Architect]](渲染管线基础架构)
|
||
- [[Unity Editor Tool Developer]] ← extends ← [[Unity Architect]](Editor 工具基础架构)
|
||
- [[Godot Gameplay Scripter]] ← parallels ← [[Unity Architect]](跨引擎设计模式对应)
|
||
- [[Roblox Systems Scripter]] ← parallels ← [[Unity Architect]](跨平台代码架构模式)
|
||
|
||
## Contradictions
|
||
- 与传统 Unity "Manager Singleton" 惯用法冲突:
|
||
- 冲突点:是否允许静态单例管理跨系统状态
|
||
- 当前观点:所有共享状态置于 SO 资产,通过 Inspector 引用,消除全局可变状态
|
||
- 对方观点:单例简单直接,访问全局状态无需显式依赖注入
|
||
|
||
## Technical Deliverables(关键代码模式)
|
||
|
||
### FloatVariable SO
|
||
```csharp
|
||
[CreateAssetMenu(menuName = "Variables/Float")]
|
||
public class FloatVariable : ScriptableObject
|
||
{
|
||
[SerializeField] private float _value;
|
||
public float Value
|
||
{
|
||
get => _value;
|
||
set { _value = value; OnValueChanged?.Invoke(value); }
|
||
}
|
||
public event Action<float> OnValueChanged;
|
||
public void SetValue(float value) => Value = value;
|
||
public void ApplyChange(float amount) => Value += amount;
|
||
}
|
||
```
|
||
|
||
### GameEvent Channel(解耦消息)
|
||
```csharp
|
||
[CreateAssetMenu(menuName = "Events/Game Event")]
|
||
public class GameEvent : ScriptableObject
|
||
{
|
||
private readonly List<GameEventListener> _listeners = new();
|
||
public void Raise()
|
||
{
|
||
for (int i = _listeners.Count - 1; i >= 0; i--)
|
||
_listeners[i].OnEventRaised();
|
||
}
|
||
public void RegisterListener(GameEventListener listener) => _listeners.Add(listener);
|
||
public void UnregisterListener(GameEventListener listener) => _listeners.Remove(listener);
|
||
}
|
||
```
|
||
|
||
### RuntimeSet(无单例实体追踪)
|
||
```csharp
|
||
public abstract class RuntimeSet<T> : ScriptableObject
|
||
{
|
||
public List<T> Items = new List<T>();
|
||
public void Add(T item) { if (!Items.Contains(item)) Items.Add(item); }
|
||
public void Remove(T item) { if (Items.Contains(item)) Items.Remove(item); }
|
||
}
|
||
```
|
||
|
||
## Workflow Process
|
||
1. **Architecture Audit**:识别硬引用、单例、God Class,映射数据流
|
||
2. **SO Asset Design**:创建 Variable SO、Event Channel SO、RuntimeSet SO,按领域组织
|
||
3. **Component Decomposition**:拆分 God MonoBehaviour 为单职责组件,通过 SO 引用连接
|
||
4. **Editor Tooling**:添加 CustomEditor/PropertyDrawer,[CreateAssetMenu],构建时架构验证
|
||
5. **Scene Architecture**:场景无持久数据,使用 Addressables + SO 配置驱动场景加载
|
||
|
||
## Success Metrics
|
||
- 生产代码中零 `GameObject.Find()` 或 `FindObjectOfType()` 调用
|
||
- 每个 MonoBehaviour < 150 行,仅处理一个关注点
|
||
- 每个 Prefab 可在空场景中独立运行无错误
|
||
- GC 分配在事件驱动路径上为零帧
|
||
- 设计师无需修改代码即可通过 Inspector 创建新游戏变量和事件
|