Update nexus wiki content

This commit is contained in:
2026-05-03 05:42:06 +08:00
parent 90f3811b83
commit 111bc65b7b
707 changed files with 32306 additions and 7289 deletions

View File

@@ -1,58 +1,114 @@
---
title: "Unity Architect"
title: "Unity Architect Agent Personality"
type: source
tags: []
date: 2026-04-26
tags: [unity, game-engineering, architecture, scriptableobjects, design-patterns]
date: 2026-05-02
---
## Source File
- [[raw/Agent/agency-agents/game-development/unity/unity-architect.md]]
- [[Agent/agency-agents/game-development/unity/unity-architect.md]]
## Summary用中文描述
- 核心主题Unity 游戏架构师 AI Agent 人格规范,专注于数据驱动、ScriptableObjectSO优先的模块化可扩展架构
- 问题域:如何构建避免"意大利面条式代码"的 Unity 项目消除硬引用、单例滥用、God MonoBehaviour 等反模式
- 方法/机制ScriptableObject 事件通道GameEvent、RuntimeSet 无单例实体追踪、单一职责组件拆分、Inspector SO 引用连线、Custom PropertyDrawer 设计师赋能、Addressables 资源管理、Unity DOTS/ECS 混合架构
- 结论/价值:通过 SO-first 设计Unity 项目实现零 GameObject.Find()、每个 MonoBehaviour < 150 行、Prefab 场景无关自包含、设计师无需代码即可创建游戏变量/事件/运行时集合
- 核心主题Unity 游戏架构中的数据驱动、模块化设计方法论,基于 ScriptableObject 构建可扩展系统
- 问题域:Unity 项目中常见的代码耦合、单体类蔓延、硬编码引用等架构腐败问题
- 方法/机制ScriptableObject First Design + 单职责组件模式 + SO 事件通道 + RuntimeSet 追踪
- 结论/价值:消除 GameObject 中心主义,通过 SO 资产实现设计师友好、可测试、易扩展的架构
## Key Claims用中文描述
- ScriptableObject-First 设计:所有共享游戏数据必须存于 ScriptableObject不通过 MonoBehaviour 字段跨场景传递
- GameEvent 事件通道:跨系统通信禁止使用 GetComponent<> 或单例,必须通过 SO 事件通道连线
- RuntimeSet 无单例追踪:全局实体追踪使用 RuntimeSet : ScriptableObject 而非静态单例
- 单一职责强制:每个 MonoBehaviour 只解决一个问题,若能用"and"描述则必须拆分
- 反模式零容忍God MonoBehaviour500+ 行、DontDestroyOnLoad 单例滥用、Update 内轮询逻辑均为禁止项
- Unity DOTS 混合架构:性能关键系统迁移至 EntitiesECS编辑器友好型游戏逻辑保留 MonoBehaviour
- 所有共享游戏数据必须存于 ScriptableObject通过 MonoBehaviour 字段跨场景传递
- 每个 MonoBehaviour 只解决一个问题,超过 150 行几乎必然违反 SRP
- 跨系统通信必须通过 SO 事件通道,禁止 `GameObject.Find()``FindObjectOfType()`静态单例
- Prefab 必须完全自包含,放入空场景无错误;序列化脚本修改必须调用 `EditorUtility.SetDirty()`
## Key Quotes
> "Every MonoBehaviour solves one problem only — if you can describe a component with 'and,' split it." — 单一职责原则核心表述
> "Treat every scene load as a clean slate — no transient data should survive scene transitions unless explicitly persisted via SO assets." — 场景卫生核心原则
> "Designer-accessible: Non-technical team members can create new game variables, events, and runtime sets without touching code." — 设计师赋能核心价值
> "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 资产形式的可序列化对象,用于存储共享数据、事件通道、运行时集合
- [[RuntimeSet]]:继承 ScriptableObject 的泛型集合类型,用于全局追踪活跃实体而不依赖单例
- [[GameEvent]]SO 形式的事件通道GameEvent : ScriptableObject用于跨系统解耦通信
- [[SingleResponsibilityPrinciple]]:每个 MonoBehaviour 只负责单一职责,超过 150 行即违反
- [[EventDrivenArchitecture]]:事件驱动替代 Update() 内轮询,消除 GC 分配
- [[DataDrivenDesign]]:数据驱动的模块化 Unity 架构设计理念
- [[ScriptableObjectEventChannel]]ScriptableObject 形式的 GameEvent 系统,通过 Raise/Register 模式实现松耦合
- [[Addressables]]Unity 资源管理系统,替代 Resources.Load(),支持细粒度内存控制和 DLC
- [[UnityDOTS]]Data-Oriented Tech StackECS + Job System + Burst Compiler用于性能关键路径
- [[EditorUtilitySetDirty]]:编辑器脚本修改 SO 数据后必须调用以确保序列化持久化
- [[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 ECSJob System + Burst Compiler 优化性能关键路径
- [[Burst Compiler]]:将 C# Job 代码编译为近乎原生性能的机器码
- [[Data-Oriented Design]]:面向数据的设计,与面向对象互补,提升 CPU 缓存命中率
## Key Entities
- [[UnityArchitect]]:本文档定义的 AI Agent 人格,数据驱动模块化架构专家,精通 ScriptableObject、职责拆分、单例消除
- [[UnityEditor]]Unity 编辑器环境ScriptableObject 通过 [CreateAssetMenu] 对设计师可见
- [[UnityDOTS]]Unity Data-Oriented Tech StackEntities、Jobs、Burst用于 CPU 密集型批量操作
- **UnityArchitect**:角色名,资深 Unity 工程师,数据驱动模块化设计专家,拒绝 GameObject 中心主义
- **FloatVariable**SO 变量资产示例,支持运行时值变更事件
- **GameEvent**SO 事件通道资产,用于跨 MonoBehaviour 解耦通信
- **RuntimeSetRegistrar**MonoBehaviour在 OnEnable/OnDisable 时向 RuntimeSet 注册/注销
## Connections
- [[UnityArchitect]] ← builds_with ← [[ScriptableObject]]
- [[UnityArchitect]] ← extends ← [[UnityMultiplayerEngineer]](网络层叠加 SO 架构)
- [[UnityArchitect]] ← complements ← [[UnityShaderGraphArtist]]SO 数据驱动视觉资产
- [[UnityArchitect]] ← complements ← [[UnityEditorToolDeveloper]]Custom PropertyDrawer 赋能 SO 设计师体验
- [[UnityArchitect]] ← builds_with ← [[UnityDOTS]](性能关键路径使用 ECS 混合架构
- [[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
- [[UnityMultiplayerEngineer]] 在客户端预测实现上存在框架差异
- UnityArchitect 侧NetworkVariable 通过 SO 引用在 MonoBehaviour 间传递状态
- UnityMultiplayerEngineer 侧NetworkVariable 直接挂载在 NetworkBehaviour 上
- 两者均遵循服务器权威原则,差异在于 SO 层抽象程度,属架构风格差异而非绝对冲突
-传统 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 创建新游戏变量和事件