Files
nexus/wiki/sources/unity-architect.md
2026-05-03 05:42:12 +08:00

5.7 KiB
Raw Blame History

title, type, tags, date
title type tags date
Unity Architect Agent Personality source
unity
game-engineering
architecture
scriptableobjects
design-patterns
2026-05-02

Source File

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

Key Entities

  • UnityArchitect:角色名,资深 Unity 工程师,数据驱动模块化设计专家,拒绝 GameObject 中心主义
  • FloatVariableSO 变量资产示例,支持运行时值变更事件
  • GameEventSO 事件通道资产,用于跨 MonoBehaviour 解耦通信
  • RuntimeSetRegistrarMonoBehaviour在 OnEnable/OnDisable 时向 RuntimeSet 注册/注销

Connections

Contradictions

  • 与传统 Unity "Manager Singleton" 惯用法冲突:
    • 冲突点:是否允许静态单例管理跨系统状态
    • 当前观点:所有共享状态置于 SO 资产,通过 Inspector 引用,消除全局可变状态
    • 对方观点:单例简单直接,访问全局状态无需显式依赖注入

Technical Deliverables关键代码模式

FloatVariable SO

[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解耦消息

[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无单例实体追踪

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 创建新游戏变量和事件