scenario-unity-architecture
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseUnity architecture (gameplay programmer / architect)
Unity 架构(gameplay programmer / architect)
Expert architecture in Unity is judged by what survives the edges: the second Play session, a destroyed object mid-await, a relaunch of the built player, a class rename, a merge of two branches, a prefab dropped into an empty scene. Data lives in assets, state lives in plain C# and files, systems talk through events they do not own, and every claim is pinned by a test the agent can run without a mouse. Target: Unity 6000.3.21f1, Input System 1.20.0, Test Framework 1.6.0, macOS. If a sibling skill named here is missing from your available skills, ask the user to install it (); unattended, proceed from tool schemas and flag the gap.
npx skills add scenario-labs/skills --skill <name>REQUIRED BACKGROUND: scenario-unity-expert (channels, review loop, 6.3 traps). Toolkit: , , plus this skill's , jobs and (a tested Game.Core / Game.Runtime / Game.Editor / tests layout).
ut_envut_runut_livescripts/ut_arch.pyscripts/AgentKit/Architecture/scripts/templates/Status (2026-09-24): every procedure ran in Unity 6000.3.21f1 on this Mac: (results in ).
tests/code/unity-architecture/run_all.sh --livearchive/tests/unity-architecture/live_results.jsonlUnity 中的专家级架构能力,体现在它能否经受住各种边界情况:第二次 Play session、await 途中对象被销毁、重新启动 built player、类重命名、两个分支合并,以及把 prefab 放入空 scene。数据存放在 assets 中,state 存放在普通 C# 与文件中,系统通过并非由自身拥有的 events 进行通信,并且每项结论都由 agent 无需使用鼠标即可运行的 test 加以验证。目标环境:Unity 6000.3.21f1、Input System 1.20.0、Test Framework 1.6.0、macOS。如果这里提到的某个 sibling skill 未包含在你的可用 skills 中,请让用户安装它();在无人值守模式下,则依据 tool schemas 继续执行并标明差距。
npx skills add scenario-labs/skills --skill <name>必需背景: scenario-unity-expert(channels、review loop、6.3 traps)。工具包:、、,以及本 skill 的 、 jobs 和 (一套经过测试的 Game.Core / Game.Runtime / Game.Editor / tests 布局)。
ut_envut_runut_livescripts/ut_arch.pyscripts/AgentKit/Architecture/scripts/templates/状态(2026-09-24): 每项流程均已在这台 Mac 上的 Unity 6000.3.21f1 中运行:(结果位于 )。
tests/code/unity-architecture/run_all.sh --livearchive/tests/unity-architecture/live_results.jsonlStance (the expert delta)
立场(专家的差异化能力)
- ScriptableObjects are definitions, never saves. Play-mode writes to an SO persist in the Editor and reset on every launch of a build (Code Monkey, 5a-ztc5gcFw [00:04:17]). Observed sharper: the write lives only in Editor memory (false, the
IsDirtyunchanged even after.asset), so a file hash never sees it; only an in-memory guard in the process that plays does (SaveAssets, the prefab SO test). A macOS player run twice started from the baked value while the save FILE carried over. Runtime modifiers apply to a struct copy (so_guard, Tarodev, tE1qH8OxO2Y [00:11:18]); live registries are runtime sets, never scene searches (Hipple, raQ3iHhE_Kk [00:40:06]). Saves: versioned JSON of ids, atomic write, backup, migrations.config.Stats - Read Enter Play Mode before trusting any Play test. With domain reload off (an option in 6.3, the default for new 6.6 projects) a static counter read 2 and a static event had 2 subscribers on the second Play (observed). Unregister static handlers on (the Manual's best practice; observed clean on its own) and reset values at
ExitingPlayMode;SubsystemRegistrationproves both. Scene reload off makes Editor startup unrepresentative, and a script change still reloads the domain (6.3 Manual).DoublePlay - Every await has an owner. Awaits survive Destroy and Play exit (Unity, eXkFPoEp3BA [00:13:28]): a token-less loop ticked 13 to 14 more times in the 0.3 s after (observed). MonoBehaviours pass
Destroy(destroyCancellationTokenwhen IO must also stop at exit); plain C# services passLifetime.Linked(this). Never await an Awaitable twice (pooled:Application.exitCancellationToken), never block on a Task. Release players skip the main-thread check: off the main thread a development player threw onAsTask(),persistentDataPath,Time.timeandtransform, the release player threw nothing (observed). Smoke-test threading in a development build.new GameObject - Designers wire, code decides. Serialized SO references are the injector designers can see (Hipple [00:14:39]). Channels decouple sender and receivers, iterate listeners backwards ([00:33:23]) and ship a debug plan: counts, a log toggle, from a job, an inspector button ([00:36:07]). UnityEvent is a serialized function call ([00:29:26]): rare designer-wired responses only (0 B per invoke measured on 6.3, but targets are hard references resolved by method name). One composition root runs first (
RaiseDebug(), git-amend, PJcBJ60C970 [00:12:01]; without it a consumer found nothing, observed) and fails loudly. Each prefab runs alone in an empty scene ([00:16:29]). Statics suit a small solo project only (Weimann, hQE8lQk9ikE [00:01:28]; Tarodev [00:03:00]), with resets. Enums only for sets fixed "by some law"; categories designers extend become SO assets ([00:46:39]).[DefaultExecutionOrder(-1000)] - Rebinding is a state machine with six traps. The action must be disabled (the package throws otherwise); Escape does not cancel a Button rebind by default; a composite head cannot be rebound; duplicates are judged on , composite parts only against earlier parts, modifier combos per
effectivePath(off by default: Shift+B also fires B); Reset All deletes the persisted overrides;shortcutKeysConsumeInputwipes existing overrides unless passedLoadBindingOverridesFromJson(samyam, csqVa2Vimao [00:12:51], [00:27:44], [00:33:22]; 1.20 manual; all tested). For the UI, start from the Rebinding UI sample: in 1.20 it already disables and disposes but lacks four fixes (false). Eachut_arch.rebind_auditof a generated input class is a separate asset: share one.new - Assemblies are a contract. A Core with holds rules testable in milliseconds; runtime asmdefs never reference editor ones (the Editor compiles it, the player build fails, observed). Test asmdefs reference
noEngineReferences;Unity.InputSystem.TestFrameworkwas not needed on 6000.3.21f1 (observed).testables - Serialized data survives refactors and merges only on purpose. for fields,
[FormerlySerializedAs]for renamed[MovedFrom]classes (without it the entry loaded as null, observed),[SerializeReference]on every[Serializable]type (6.3 tolerated its absence; 6.4 requires it per the version notes). UnityYAMLMerge exits 2 on any conflicted field even with[SerializeReference]/-l, and without them writes the BASE value (observed): check the exit code, then open the result in Unity.-r
- ScriptableObject 是定义,绝不是存档。 在 Play mode 中对 SO 的写入会保留在 Editor 中,并且每次启动 build 时都会重置(Code Monkey, 5a-ztc5gcFw [00:04:17])。更精确的观察结果是:该写入只存在于 Editor 内存中(为 false,即使调用
IsDirty后SaveAssets也未改变),因此 file hash 永远检测不到它;只有实际运行游戏的进程中的 in-memory guard 才能检测到(.asset、prefab SO test)。macOS player 连续运行两次时,第二次仍从 baked value 开始,而 save FILE 会保留下来。Runtime modifiers 应作用于 struct copy(so_guard,Tarodev, tE1qH8OxO2Y [00:11:18]);live registries 应使用 runtime sets,绝不能通过 scene searches 获取(Hipple, raQ3iHhE_Kk [00:40:06])。Saves:包含 ids 的 versioned JSON、atomic write、backup 和 migrations。config.Stats - 信任任何 Play test 之前,先读取 Enter Play Mode 设置。 关闭 domain reload(6.3 中的一项选项,也是 6.6 新项目的默认设置)时,第二次 Play 中 static counter 的读数为 2,static event 有 2 个 subscribers(实测)。在 中注销 static handlers(Manual 推荐的 best practice;单独使用时实测结果干净),并在
ExitingPlayMode中重置值;SubsystemRegistration可同时证明这两点。关闭 scene reload 会使 Editor startup 不具代表性,而 script 变更仍会 reload domain(6.3 Manual)。DoublePlay - 每个 await 都必须有 owner。 Awaits 会在 Destroy 和 Play exit 之后继续存在(Unity, eXkFPoEp3BA [00:13:28]):一个不带 token 的 loop 在 后的 0.3 s 内又 tick 了 13 到 14 次(实测)。MonoBehaviours 应传入
Destroy(IO 也必须在退出时停止时使用destroyCancellationToken);普通 C# services 应传入Lifetime.Linked(this)。绝不要 await 同一个 Awaitable 两次(pooled:使用Application.exitCancellationToken),也绝不要阻塞等待 Task。Release players 会跳过 main-thread check:在非 main thread 上,development player 在访问AsTask()、persistentDataPath、Time.time和执行transform时抛出异常,而 release player 未抛出任何异常(实测)。应在 development build 中对 threading 进行 smoke test。new GameObject - Designers 负责 wiring,code 负责决策。 序列化的 SO references 是 designers 可见的 injector(Hipple [00:14:39])。Channels 解耦 sender 与 receivers、反向遍历 listeners([00:33:23]),并提供 debug plan:counts、log toggle、由 job 触发的 、inspector button([00:36:07])。UnityEvent 是一种 serialized function call:仅用于少见的、由 designer wiring 的 responses(6.3 中实测每次 invoke 为 0 B,但 targets 是通过 method name 解析的 hard references)。一个 composition root 应最先运行(
RaiseDebug()、git-amend、PJcBJ60C970 [00:12:01];缺少它时,consumer 找不到任何内容,实测),并且在失败时明确报错。每个 prefab 都应在空 scene 中独立运行([00:16:29])。Statics 仅适合小型 solo project(Weimann, hQE8lQk9ikE [00:01:28];Tarodev [00:03:00]),并且必须带 resets。Enums 仅适用于由某种“规则”固定的集合;designers 可以扩展的 categories 应变为 SO assets([00:46:39])。[DefaultExecutionOrder(-1000)] - Rebinding 是一个包含六个陷阱的 state machine。 必须先禁用 action(否则 package 会抛出异常);默认情况下,Escape 不会取消 Button rebind;composite head 无法 rebind;duplicates 根据 判断,composite parts 只与更早的 parts 比较,modifier combos 则取决于
effectivePath(默认关闭:Shift+B 也会触发 B);Reset All 会删除持久化的 overrides;除非传入shortcutKeysConsumeInput,否则false会清空现有 overrides(samyam, csqVa2Vimao [00:12:51]、[00:27:44]、[00:33:22];1.20 manual;均已测试)。对于 UI,应从 Rebinding UI sample 入手:在 1.20 中,它已经会 disable 和 dispose,但仍缺少四项修复(LoadBindingOverridesFromJson)。每次ut_arch.rebind_auditgenerated input class 都会创建一个独立 asset:应共享同一个实例。new - Assemblies 是一份 contract。 使用 的 Core 承载可在数毫秒内测试的 rules;runtime asmdefs 绝不能引用 editor asmdefs(Editor 可以完成编译,但 player build 会失败,实测)。Test asmdefs 应引用
noEngineReferences;在 6000.3.21f1 上不需要Unity.InputSystem.TestFramework(实测)。testables - Serialized data 只有经过有意设计,才能在 refactors 和 merges 中存活。 Fields 使用 ,重命名的
[FormerlySerializedAs]classes 使用[SerializeReference](缺少后者时,entry 会加载为 null,实测),每个[MovedFrom]type 都要添加[SerializeReference](6.3 可以缺少该特性,但根据 version notes,6.4 要求必须添加)。即使带有[Serializable]/-l,UnityYAMLMerge 遇到任何 conflicted field 都会以 2 退出;不带这些参数时则会写入 BASE value(实测):应检查 exit code,然后在 Unity 中打开结果。-r
Establish first
首先明确
Team shape (who wires behavior: designers or programmers), project lifetime, target platforms (Web has no managed threads), Enter Play Mode setting, input devices (keyboard-mouse, gamepad, touch, local multiplayer) and modifier shortcuts, save needs (slots, cloud, migrations), VCS (Git + LFS by default). Defaults: project-wide actions, Game.Core/Runtime/Editor/Tests asmdefs, SO definitions + plain C# state, event channels between systems, runtime sets for registries, one , JSON saves under , Git with the UnityYAMLMerge driver. Run and write its answers into the plan.
GameRootpersistentDataPathArchJobs.ProjectFacts团队形态(由 designers 还是 programmers wiring behavior)、project lifetime、target platforms(Web 不支持 managed threads)、Enter Play Mode 设置、input devices(keyboard-mouse、gamepad、touch、local multiplayer)和 modifier shortcuts、save needs(slots、cloud、migrations)、VCS(默认使用 Git + LFS)。默认方案:project-wide actions、Game.Core/Runtime/Editor/Tests asmdefs、SO definitions + plain C# state、系统之间的 event channels、用于 registries 的 runtime sets、唯一的 、存放在 下的 JSON saves,以及配置 UnityYAMLMerge driver 的 Git。运行 ,并将其答案写入 plan。
GameRootpersistentDataPathArchJobs.ProjectFactsWorkflow
Workflow
- Scaffold and compile. Goal: rules in pure C#. How: ,
ut_arch.install(P)(A1), thenut_arch.scaffold(P)(ArchJobs.ProjectFacts). GATE: zero compile errors and warnings;Unity -batchmode -nographics -quit -executeMethod AgentKit.Architecture.ArchJobs.ProjectFacts: Game.CoreArchJobs.AssemblyGraph,engine_refs == 0.violations == [] - Data as assets. Goal: definitions designers edit. How: with
ArchJobs.CreateAssets(ut_arch.item_specs()edits,SerializedObjectformanaged_refslists, SetDirty only on change) (A2, A13). GATE: second run all[SerializeReference];unchangedclean.ItemDatabaseValidator - Core systems with tests. Goal: inventory, health, events, sets. How: templates; . GATE: all pass;
ut_run.run_tests(P, "EditMode", assemblies="Game.Tests.EditMode")no warn or error in runtime code (A10).ut_arch.code_lint - Save and load. Goal: state that survives relaunch. How: (A3). GATE: EditMode round trip, corrupt-file fallback, v1 migration;
SaveServiceacross two editor processes; a player run twice for persistence claims (A4); a development player when saves touch threads (A12).CrossProcessSave - Input. Goal: every device, rebinding that persists and resets. How: project-wide actions, ,
InputContext,RebindFlow,BindingStoreedited as JSON;.inputactions(A5, A15). GATE:ArchInputAudit.Audittests per trap; audit withoutInputTestFixtureormissing_scheme;duplicate_bindingmissing nothing.rebind_audit - Async and lifecycle. Goal: no orphan work. How: with a token,
async Awaitable Start(), PlayMode suite; async tests as aAsTaskreturning the inner Awaitable, or[UnityTest](A6, A7, A14). GATE: no tick after Destroy; prefab isolation and prefab SO guard pass.async Task - Play-mode hardening. Goal: session 2 equals session 1, events reach responses. How: , then
ArchJobs.StaticStateAuditwithArchPlayMode.DoublePlayandso_guard(invokeon each channel) in the project's mode (A8, A11). GATE: noRaiseDebugin own assemblies; watched values equal across sessions;arch.static_without_reset; every invokeso_changed_in_memory == []with its response counted.ok - Version control. Goal: merges and moves never break references. How: ,
ArchJobs.SetVcsSettings,ut_arch.write_vcs_files,git_setup_unity_merge,meta_audit, thenyaml_merge(A9). GATE:ArchJobs.InspectAsset;meta_audit.oknot in LFS; clean merges exit 0 and deserialize; conflicts stay unmerged with a report..meta - Hand off with evidence (scenario-unity-expert report format): Unity call per step, Verified, Assumed.
- Scaffold 并完成编译。 目标:将 rules 放入 pure C#。方法:执行 、
ut_arch.install(P)(A1),然后运行ut_arch.scaffold(P)(ArchJobs.ProjectFacts)。GATE:零 compile errors 和 warnings;Unity -batchmode -nographics -quit -executeMethod AgentKit.Architecture.ArchJobs.ProjectFacts:Game.CoreArchJobs.AssemblyGraph,engine_refs == 0。violations == [] - 将数据作为 assets。 目标:提供 designers 可编辑的 definitions。方法:使用 和
ArchJobs.CreateAssets(ut_arch.item_specs()edits、用于SerializedObjectlists 的[SerializeReference]、仅在发生变化时调用 SetDirty)(A2, A13)。GATE:第二次运行时全部为managed_refs;unchangedclean。ItemDatabaseValidator - 使用 tests 构建 core systems。 目标:inventory、health、events、sets。方法:templates;。GATE:全部通过;
ut_run.run_tests(P, "EditMode", assemblies="Game.Tests.EditMode")在 runtime code 中无 warn 或 error(A10)。ut_arch.code_lint - Save 与 load。 目标:state 在 relaunch 后仍然存在。方法:(A3)。GATE:EditMode round trip、corrupt-file fallback、v1 migration;通过两个 editor processes 执行
SaveService;对于 persistence claims,执行两次 player run(A4);当 saves 涉及 threads 时,执行 development player(A12)。CrossProcessSave - Input。 目标:支持所有 devices、持久化且可重置的 rebinding。方法:project-wide actions、、
InputContext、RebindFlow、以 JSON 编辑BindingStore;.inputactions(A5, A15)。GATE:针对每个陷阱的ArchInputAudit.Audittests;audit 不出现InputTestFixture或missing_scheme;duplicate_binding无任何缺项。rebind_audit - Async 与 lifecycle。 目标:不存在 orphan work。方法:使用带 token 的 、
async Awaitable Start()、PlayMode suite;async tests 使用返回 inner Awaitable 的AsTask,或使用[UnityTest](A6, A7, A14)。GATE:Destroy 后不再 tick;prefab isolation 和 prefab SO guard 通过。async Task - Play-mode hardening。 目标:session 2 等同于 session 1,events 能到达 responses。方法:,然后在项目模式下运行
ArchJobs.StaticStateAudit,并带上ArchPlayMode.DoublePlay与so_guard(每个 channel 上执行invoke)(A8, A11)。GATE:自有 assemblies 中不存在RaiseDebug;watched values 在各 session 间相等;arch.static_without_reset;每次 invoke 均为so_changed_in_memory == [],且其 response 计数正确。ok - Version control。 目标:merges 和 moves 永远不会破坏 references。方法:、
ArchJobs.SetVcsSettings、ut_arch.write_vcs_files、git_setup_unity_merge、meta_audit,然后执行yaml_merge(A9)。GATE:ArchJobs.InspectAsset;meta_audit.ok不在 LFS 中;clean merges 以 0 退出且可以反序列化;conflicts 保持 unmerged 状态并生成 report。.meta - 携带 evidence 交接(scenario-unity-expert report format):每一步给出 Unity call、Verified、Assumed。
Numbers
Numbers
| Value | Relative to | Source |
|---|---|---|
| 11 to 13 s | one batch job on this project (editor boot included) | observed |
| about 11 s / 16 s | EditMode suite (33 tests) / PlayMode suite (17 tests), final run | observed |
| 13 to 14 ticks | token-less 0.02 s Awaitable loop in the 0.3 s after | observed |
| 2 / 2 | static counter / static event subscribers in Play session 2, domain reload off | observed |
| 4 of 6 / 0 of 6 | Unity calls that threw off the main thread in a development / release macOS player | observed |
| 0 B | heap growth over 10,000 channel raises or persistent UnityEvent invokes after warm-up | observed |
| about 37,000 to 61,000 fps | batch | observed |
| 0.05 s; false | | package source 1.20; observed |
next | Task continuation started on the main thread | 6.3 Manual |
| about 500 KB | binary size above which Git LFS pays | Pettersen 2016 |
| exit 0 / 2 | UnityYAMLMerge clean / any conflicted field (also with | observed |
| 114.7 MB / 311.2 MB | macOS Mono release / development player of a probe scene | observed |
| 数值 | 相对于 | 来源 |
|---|---|---|
| 11 到 13 秒 | 此项目上的一个 batch job(含 editor boot) | 实测 |
| 约 11 秒 / 16 秒 | 最终运行中的 EditMode suite(33 tests)/ PlayMode suite(17 tests) | 实测 |
| 13 到 14 ticks | | 实测 |
| 2 / 2 | 关闭 domain reload 时,Play session 2 中的 static counter / static event subscribers | 实测 |
| 4 of 6 / 0 of 6 | development / release macOS player 中在非 main thread 上抛出异常的 Unity calls | 实测 |
| 0 B | warm-up 后执行 10,000 次 channel raises 或持久 UnityEvent invokes 的 heap growth | 实测 |
| 约 37,000 到 61,000 fps | batch | 实测 |
| 0.05 秒;false | | package source 1.20;实测 |
next | 在 main thread 上启动的 Task continuation | 6.3 Manual |
| 约 500 KB | Git LFS 开始值得使用的 binary size 阈值 | Pettersen 2016 |
| exit 0 / 2 | UnityYAMLMerge clean / 存在任何 conflicted field(即使带有 | 实测 |
| 114.7 MB / 311.2 MB | probe scene 的 macOS Mono release / development player | 实测 |
Quality gates
Quality gates
- Measurable: zero compile errors and warnings; ; EditMode and PlayMode
AssemblyGraph.violations == []in the full suite, not only single tests;failed == 0no warn or error in runtime code;code_lintand the prefab SO test clean (so_guardSnapshotAssetsonly proves editor tools saved nothing);changed_on_disk == []clean;StaticStateAuditsessions equal;DoublePlaywarn 0;ArchInputAuditcomplete;rebind_audit; merge exit codes checked; player relaunch report (A4) and development-player report (A12) when persistence or threads are claimed.meta_audit.ok - Visual (few): after a scene merge, a camera capture before and after (scenario-unity-expert ); a rebinding screen shows the new binding text (scenario-unity-ui).
AgentCapture
- 可衡量: 零 compile errors 和 warnings;;完整 suite 中的 EditMode 和 PlayMode 均为
AssemblyGraph.violations == [],而不只是单个 tests;failed == 0在 runtime code 中无 warn 或 error;code_lint和 prefab SO test clean(so_guard的SnapshotAssets只能证明 editor tools 没有保存任何内容);changed_on_disk == []clean;StaticStateAuditsessions 相等;DoublePlaywarn 0;ArchInputAudit完整;rebind_audit;检查 merge exit codes;当声称涉及 persistence 或 threads 时,提供 player relaunch report(A4)和 development-player report(A12)。meta_audit.ok - 视觉检查(少量): scene merge 前后各进行一次 camera capture(scenario-unity-expert );rebinding screen 显示新的 binding text(scenario-unity-ui)。
AgentCapture
Common mistakes
Common mistakes
| Mistake | What it looks like | Fix |
|---|---|---|
| save stored in an SO | works in the Editor, lost after relaunch of the build | |
| SO guard by file hash | passes while Play writes an SO | |
| session state in an unreferenced SO | value back to baked after a scene load, in the build | keep it referenced or hold it in C# |
| statics with domain reload off | second Play starts at 2, handler runs twice | ExitingPlayMode unregister + SubsystemRegistration reset |
| await without token | logic runs after the object died or Play ended | |
| awaiting an Awaitable twice | exception or hang | |
| threads checked in a release build only | fine now, undefined later | development player smoke test (A12) |
| listeners iterated forward | a self-removing response skips the next | iterate backwards |
| composition root without execution order | a consumer's Awake finds no service | |
| rebinding an enabled action | | |
Button rebind without | Escape becomes the binding | |
| Reset All keeps the file; loads not layered | old rebinds return; earlier overrides vanish | |
| null after fixture tests; pairing breaks | |
| a generated input class per consumer | a rebind shows on one screen only | one shared instance |
| runtime asmdef references editor asmdef | Editor fine, player build fails | |
class renamed behind | entries load as null | |
| trusting a merge output | conflicted field silently back to base | check exit 2, resolve, |
| 错误 | 表现 | 修复 |
|---|---|---|
| 存档存储在 SO 中 | 在 Editor 中有效,但 build 重新启动后丢失 | |
| 使用 file hash 保护 SO | 检查通过,但 Play 实际写入了 SO | 在正在运行的进程中使用 |
| session state 位于未引用的 SO 中 | scene load 后或 build 中,值恢复为 baked value | 保持其被引用,或保存在 C# 中 |
| 关闭 domain reload 时使用 statics | 第二次 Play 从 2 开始,handler 运行两次 | ExitingPlayMode unregister + SubsystemRegistration reset |
| await 不带 token | logic 在对象销毁或 Play 结束后仍运行 | |
| 两次 await 同一个 Awaitable | exception 或 hang | 只调用一次 |
| 仅在 release build 中检查 threads | 当前正常,以后结果未定义 | development player smoke test(A12) |
| 正向遍历 listeners | self-removing response 会跳过下一个 | 反向遍历 |
| composition root 缺少 execution order | consumer 的 Awake 找不到 service | |
| rebind 一个已启用的 action | | |
Button rebind 未使用 | Escape 成为 binding | |
| Reset All 保留文件;loads 未分层 | 旧 rebinds 恢复;较早的 overrides 消失 | |
在 tests 或使用 PlayerInput 时访问 | fixture tests 后为 null;pairing 损坏 | |
| 每个 consumer 创建一个 generated input class | rebind 只显示在一个 screen 上 | 共享同一个实例 |
| runtime asmdef 引用 editor asmdef | Editor 正常,player build 失败 | |
重命名 | entries 加载为 null | 在同一次变更中添加 |
| 信任 merge 输出 | conflicted field 静默恢复为 base | 检查 exit 2、解决冲突、执行 |
Handoffs
Handoffs
- Receives from scenario-unity-expert: brief, channel, project facts. From scenario-unity-gameplay: which systems need health, damage, state machines (the FSM pattern lives there).
- Delivers to scenario-unity-ui: ,
RebindFlow,BindingStore, channels (withInputContext) for HUD and settings screens, with tests. To scenario-unity-gameplay:RaiseDebug,IDamageable,Health,Services, runtime sets. To scenario-unity-pipeline-automation: asmdef layout,GameRoot, development builds,run_tests(..., assemblies=...)/.gitignore, merge driver. To scenario-unity-performance: GC per frame (scenario-unity-expert.gitattributes), per-object Awaitable loops. To scenario-unity-web: no managed threads (SaveAsync stays synchronous, noAgentProfile). To scenario-unity-mobile: touch schemes,Task.Delay. Packet: files written, tests with totals, audits with counts, Verified and Assumed.persistentDataPath
- 接收自 scenario-unity-expert:brief、channel、project facts。来自 scenario-unity-gameplay:哪些 systems 需要 health、damage、state machines(FSM pattern 位于其中)。
- 交付给 scenario-unity-ui:用于 HUD 和 settings screens 的 、
RebindFlow、BindingStore、channels(包含InputContext),并附带 tests。交付给 scenario-unity-gameplay:RaiseDebug、IDamageable、Health、Services、runtime sets。交付给 scenario-unity-pipeline-automation:asmdef layout、GameRoot、development builds、run_tests(..., assemblies=...)/.gitignore、merge driver。交付给 scenario-unity-performance:每帧 GC(scenario-unity-expert.gitattributes)、per-object Awaitable loops。交付给 scenario-unity-web:no managed threads(SaveAsync 保持 synchronous,不使用AgentProfile)。交付给 scenario-unity-mobile:touch schemes、Task.Delay。Packet:写入的文件、包含总数的 tests、包含计数的 audits、Verified 和 Assumed。persistentDataPath
Unity 6.3 notes
Unity 6.3 notes
- Enter Play Mode is a dropdown ("When entering Play Mode"); 6.6 new projects default to "Reload Scene only"; 6.5 adds code lifecycle attributes and .
AutoStaticsCleanup - (the sort mode is obsolete from 6.4);
FindObjectsByType<T>(FindObjectsSortMode.None)only on fields;[SerializeField]becomes a compile error in 6.5 (GetInstanceID);EntityIdtypes must be[SerializeReference]from 6.4 (version notes, unverified there).[Serializable] - Templates run the Input System only (legacy throws); Input System 1.20 bundled;
Input.*works with it only from 6.4.OnMouseDown - : verified live on 6000.3.21f1 (
Object.Destroy, 2026-09-24) thatLifecycleTestsreaches every descendant (four levels); the 6.4 upgrade guide and the version notes describe pre-6.4 editors as "only direct children", so keep the idempotentOnDisableunregistration for older editors.OnDestroy - Force Text and Visible Meta Files are the 6.3 defaults (observed); 6.6 turns YAML word wrap off and removes "Reduce Version Control Noise".
- Enter Play Mode 是一个 dropdown(“When entering Play Mode”);6.6 新项目默认使用“Reload Scene only”;6.5 新增 code lifecycle attributes 和 。
AutoStaticsCleanup - (sort mode 从 6.4 起废弃);
FindObjectsByType<T>(FindObjectsSortMode.None)只能用于 fields;[SerializeField]在 6.5 中会成为 compile error(GetInstanceID);从 6.4 起,EntityIdtypes 必须添加[SerializeReference](version notes,未在 6.4 上验证)。[Serializable] - Templates 仅运行 Input System(legacy 会抛出异常);内置 Input System 1.20;
Input.*从 6.4 起才能与其协同工作。OnMouseDown - :已在 6000.3.21f1 上实时验证(
Object.Destroy,2026-09-24),LifecycleTests可到达每一层 descendant(共四层);6.4 upgrade guide 和 version notes 将 6.4 之前的 editors 描述为“only direct children”,因此应继续在较旧的 editors 中保留幂等的OnDisableunregistration。OnDestroy - Force Text 和 Visible Meta Files 是 6.3 的默认设置(实测);6.6 会关闭 YAML word wrap,并移除“Reduce Version Control Noise”。
References
References
- : A1 to A15 with full code, live test and recorded result.
references/procedures.md - : principles by expert with timestamps, decision tables, every observation.
references/expert-notes.md - : the self-review rubric.
references/critique.md - : menus and windows for the same tasks.
references/gui-paths.md - : sources, credentials, URLs, best timestamps, revision history.
references/sources.md - ,
scripts/ut_arch.py,scripts/AgentKit/Architecture/*.cs: the tested code.scripts/templates/
- :A1 到 A15,包含完整代码、live test 和记录结果。
references/procedures.md - :专家原则、时间戳、决策表和所有观察结果。
references/expert-notes.md - :self-review rubric。
references/critique.md - :完成相同任务所使用的 menus 和 windows。
references/gui-paths.md - :sources、credentials、URLs、最佳时间戳和 revision history。
references/sources.md - 、
scripts/ut_arch.py、scripts/AgentKit/Architecture/*.cs:经过测试的代码。scripts/templates/