unity-scriptdesign

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Before calling any skill in this module: if you are about to call a skill with parameters guessed from its name or description, STOP — read this file (or fetch its schema via
GET /skills/recommend?includeSchema=true
) first. If you already have the parameter definitions from recommend/schema, you may proceed straight to dryRun.
调用本模块中的任何技能之前:如果您打算根据技能名称或描述猜测参数来调用技能,请停止——先阅读本文档(或通过
GET /skills/recommend?includeSchema=true
获取其 schema)。如果您已经从推荐/schema中获得了参数定义,可以直接进行dryRun。

Triggers

触发场景

  • Reviewing code quality
  • Untangling tightly-coupled scripts
  • Planning a refactor for maintainability
  • 审查代码质量、理顺高耦合脚本、为可维护性规划重构
  • 审查代码质量
  • 梳理高耦合脚本
  • 为可维护性规划重构
  • 审查代码质量、理顺高耦合脚本、为可维护性规划重构

Unity Script Design Review

Unity脚本设计审查

Use this skill before creating gameplay scripts, or after scripts are generated and need a design pass.
在创建游戏玩法脚本之前,或脚本生成后需要进行设计审查时,使用本技能。

Review Checklist

审查清单

  • Responsibility: does the script have one clear job?
  • Role: should it really be a
    MonoBehaviour
    ,
    ScriptableObject
    , or plain C# class?
  • Coupling: are dependencies explicit instead of hidden globals or deep scene lookups?
  • Communication: should this be a direct reference, interface call, or event?
  • Performance: is there unnecessary
    Update
    , repeated
    Find
    , avoidable allocation, or reflection in hot paths?
  • Lifecycle: are subscriptions, timers, and async work cleaned up clearly?
  • Inspector UX: are serialized fields private, grouped, and explained?
  • Testability: can the core logic move into a plain C# class?
  • Naming: do class and field names explain intent without cryptic abbreviations?
  • 职责:脚本是否有明确单一的职责?
  • 角色定位:它是否真的应该是
    MonoBehaviour
    ScriptableObject
    还是普通C#类?
  • 耦合性:依赖关系是否明确,而非使用隐藏全局变量或深度场景查找?
  • 通信方式:应该使用直接引用、接口调用还是事件?
  • 性能:热路径中是否存在不必要的
    Update
    、重复的
    Find
    、可避免的内存分配或反射操作?
  • 生命周期:订阅、计时器和异步任务是否被清晰地清理?
  • 检视器用户体验:序列化字段是否为私有、分组并配有说明?
  • 可测试性:核心逻辑能否迁移到普通C#类中?
  • 命名:类和字段名称是否能清晰表达意图,无晦涩缩写?

Data Lifecycle Boundary

数据生命周期边界

The Review Checklist above asks "where does this class live". Ask the same question for every field. Every piece of state has one of three lifecycles, and putting a field on the wrong one is the most common cause of "why did this break when the designer tweaked a value" and "why are my unit tests flaky".
LifecycleWhen the value is decidedWhere it belongsTypical idiom
Authoring-timeBy a designer in the Editor, before Play
ScriptableObject
asset, or
[SerializeField] private
on a prefab
Immutable at runtime; read via
_config.Speed
Composition-timeOnce per scene/instance, at
Awake
/
Start
private
field, assigned from
GetComponent
/
GetComponentInChildren
/ ctor arg
Cached reference, no per-frame lookup
Runtime-mutableEvery frame or on gameplay events
private
backing field +
public
read-only property + event
Exposed via
public float Health { get; private set; }
+
OnHealthChanged
上面的审查清单会问“这个应归属何处”。请对每个字段提出同样的问题。每一项状态都属于三种生命周期之一,将字段归到错误的生命周期是导致“为什么设计师调整值后程序就崩溃了”以及“为什么我的单元测试不稳定”的最常见原因。
生命周期值的确定时机归属位置典型用法
创作阶段(Authoring-time)由设计师在编辑器中、进入Play模式前确定
ScriptableObject
资源,或预制体上的
[SerializeField] private
字段
运行时不可变;通过
_config.Speed
读取
组合阶段(Composition-time)每个场景/实例在
Awake
/
Start
时确定一次
private
字段,通过
GetComponent
/
GetComponentInChildren
/ 构造函数参数赋值
缓存引用,避免每帧查找
运行时可变(Runtime-mutable)每帧或在游戏玩法事件触发时确定
private
后备字段 +
public
只读属性 + 事件
通过
public float Health { get; private set; }
+
OnHealthChanged
暴露

Typical assignments

典型分配示例

  • Weapon damage / fire rate / clip size → Authoring-time (ScriptableObject so balance can be hot-swapped).
  • Enemy AI's current target
    Transform
    Composition-time if set once at spawn, Runtime-mutable if re-targeted each frame.
  • Player current HP → Runtime-mutable with event. Never
    public float hp;
    .
  • Reference to
    Rigidbody
    /
    Animator
    on the same GameObject → Composition-time, cached in
    Awake
    .
  • Level music track → Authoring-time via ScriptableObject level descriptor.
  • "Is in combat" flag → Runtime-mutable, but usually derived from other state — review whether it should be a field at all.
  • 武器伤害/射速/弹夹容量 → 创作阶段(Authoring-time)(使用ScriptableObject可热切换平衡参数)。
  • 敌人AI的当前目标
    Transform
    → 若在生成时设置一次则为组合阶段(Composition-time),若每帧重新定位则为运行时可变(Runtime-mutable)
  • 玩家当前生命值 → **运行时可变(Runtime-mutable)**并搭配事件。绝不要使用
    public float hp;
  • 同一GameObject上的
    Rigidbody
    /
    Animator
    引用 → 组合阶段(Composition-time),在
    Awake
    中缓存。
  • 关卡音乐曲目 → 通过ScriptableObject关卡描述符设置为创作阶段(Authoring-time)
  • “是否处于战斗中”标记 → 运行时可变(Runtime-mutable),但通常由其他状态派生而来——需审查它是否真的需要作为字段存在。

Why the separation matters

为何要区分生命周期

Mixing the three lifecycles is what turns a clean class into a god object. A
MonoBehaviour
whose
public float speed
is edited by both the Inspector and a power-up script has two owners and no invariant; a bug in either path corrupts the other. The ECS baking pipeline makes this distinction a hard architectural boundary (Authoring → Baker → System), and the discipline transfers directly: if you would not mix an Authoring component with runtime write-back in ECS, do not mix them in a MonoBehaviour either. Source:
EntitiesSamples/Docs/baking.md:5-16
.
混淆这三种生命周期会将一个简洁的类变成上帝对象。如果一个
MonoBehaviour
public float speed
既被检视器编辑,又被增益脚本修改,那么它有两个所有者且没有不变性;任一路径出现bug都会影响另一路径。ECS烘焙管线将这种区分作为严格的架构边界(创作→烘焙器→系统),这种规范同样适用于MonoBehaviour:如果您不会在ECS中混合创作组件与运行时回写,那么在MonoBehaviour中也不要这样做。来源:
EntitiesSamples/Docs/baking.md:5-16
.

Guardrails

约束规则

Mode: Documentation only — no REST skills to gate; load freely under any operating mode (Approval / Auto / Bypass).
  • Prefer descriptive names over local shorthand.
  • Do not “optimize” readability away for imagined productivity gains.
  • Do not recommend complex patterns if a smaller refactor fixes the real problem.
模式:仅文档——无需REST技能权限;可在任何操作模式(Approval / Auto / Bypass)下自由加载。
  • 优先使用描述性名称,而非局部简写。
  • 不要为了臆想的效率提升而牺牲可读性。
  • 如果小型重构就能解决实际问题,不要推荐复杂模式。

Output Format

输出格式

  • Keep: what is already good
  • Simplify: what should stay straightforward
  • Refactor: the highest-value structural change
  • Performance notes: only real hotspots, not theoretical micro-optimizations
  • Maintainability notes: naming, ownership, coupling, editor usability
  • 保留:现有优秀的部分
  • 简化:应保持简洁的部分
  • 重构:价值最高的结构性变更
  • 性能说明:仅针对实际热点,而非理论上的微优化
  • 可维护性说明:命名、所有权、耦合性、编辑器易用性