unity-scriptdesign
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBefore 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) 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。GET /skills/recommend?includeSchema=true
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, or plain C# class?ScriptableObject - 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 , repeated
Update, avoidable allocation, or reflection in hot paths?Find - 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还是普通C#类?ScriptableObject - 耦合性:依赖关系是否明确,而非使用隐藏全局变量或深度场景查找?
- 通信方式:应该使用直接引用、接口调用还是事件?
- 性能:热路径中是否存在不必要的、重复的
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".
| Lifecycle | When the value is decided | Where it belongs | Typical idiom |
|---|---|---|---|
| Authoring-time | By a designer in the Editor, before Play | | Immutable at runtime; read via |
| Composition-time | Once per scene/instance, at | | Cached reference, no per-frame lookup |
| Runtime-mutable | Every frame or on gameplay events | | Exposed via |
上面的审查清单会问“这个类应归属何处”。请对每个字段提出同样的问题。每一项状态都属于三种生命周期之一,将字段归到错误的生命周期是导致“为什么设计师调整值后程序就崩溃了”以及“为什么我的单元测试不稳定”的最常见原因。
| 生命周期 | 值的确定时机 | 归属位置 | 典型用法 |
|---|---|---|---|
| 创作阶段(Authoring-time) | 由设计师在编辑器中、进入Play模式前确定 | | 运行时不可变;通过 |
| 组合阶段(Composition-time) | 每个场景/实例在 | | 缓存引用,避免每帧查找 |
| 运行时可变(Runtime-mutable) | 每帧或在游戏玩法事件触发时确定 | | 通过 |
Typical assignments
典型分配示例
- Weapon damage / fire rate / clip size → Authoring-time (ScriptableObject so balance can be hot-swapped).
- Enemy AI's current target → Composition-time if set once at spawn, Runtime-mutable if re-targeted each frame.
Transform - Player current HP → Runtime-mutable with event. Never .
public float hp; - Reference to /
Rigidbodyon the same GameObject → Composition-time, cached inAnimator.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的当前目标→ 若在生成时设置一次则为组合阶段(Composition-time),若每帧重新定位则为运行时可变(Runtime-mutable)。
Transform - 玩家当前生命值 → **运行时可变(Runtime-mutable)**并搭配事件。绝不要使用。
public float hp; - 同一GameObject上的/
Rigidbody引用 → 组合阶段(Composition-time),在Animator中缓存。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 whose 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: .
MonoBehaviourpublic float speedEntitiesSamples/Docs/baking.md:5-16混淆这三种生命周期会将一个简洁的类变成上帝对象。如果一个的既被检视器编辑,又被增益脚本修改,那么它有两个所有者且没有不变性;任一路径出现bug都会影响另一路径。ECS烘焙管线将这种区分作为严格的架构边界(创作→烘焙器→系统),这种规范同样适用于MonoBehaviour:如果您不会在ECS中混合创作组件与运行时回写,那么在MonoBehaviour中也不要这样做。来源:.
MonoBehaviourpublic float speedEntitiesSamples/Docs/baking.md:5-16Guardrails
约束规则
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
- 保留:现有优秀的部分
- 简化:应保持简洁的部分
- 重构:价值最高的结构性变更
- 性能说明:仅针对实际热点,而非理论上的微优化
- 可维护性说明:命名、所有权、耦合性、编辑器易用性