From 57f0c6d4050c840169ce1f71e220e7ddf4ada5ea Mon Sep 17 00:00:00 2001 From: hatayama Date: Fri, 6 Mar 2026 21:41:48 +0900 Subject: [PATCH 01/13] =?UTF-8?q?uloop-execute-dynamic-code=E3=82=B9?= =?UTF-8?q?=E3=82=AD=E3=83=AB=E3=81=ABcontext:=20fork=E3=82=92=E9=81=A9?= =?UTF-8?q?=E7=94=A8=E3=81=97=E3=80=81=E6=9C=AA=E8=A8=98=E8=BC=89=E3=83=AA?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=83=AC=E3=83=B3=E3=82=B9=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 9個のリファレンスファイル(合計2,215行)を持つこのスキルは、 メインコンテキストを大量に消費するため、context: forkで サブエージェントに隔離することでコンテキスト汚染を防ぐ。 また、実在するが未記載だった4つのリファレンス(batch, cleanup, undo, selection operations)をSKILL.mdに追記し、 サブエージェント向けのWorkflowセクションを追加。 --- .../uloop-execute-dynamic-code/SKILL.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.claude/skills/uloop-execute-dynamic-code/SKILL.md b/.claude/skills/uloop-execute-dynamic-code/SKILL.md index 4eba4f007..8cb7c8cf7 100644 --- a/.claude/skills/uloop-execute-dynamic-code/SKILL.md +++ b/.claude/skills/uloop-execute-dynamic-code/SKILL.md @@ -1,6 +1,13 @@ --- name: uloop-execute-dynamic-code description: "Execute C# code dynamically in Unity Editor. Use when you need to: (1) Wire prefab/material references and AddComponent operations, (2) Edit SerializedObject properties and reference wiring, (3) Perform scene/hierarchy edits and batch operations. NOT for file I/O or script authoring." +context: fork +agent: Explore +allowed-tools: + - Read + - Bash + - Grep + - Glob --- # uloop execute-dynamic-code @@ -99,3 +106,20 @@ For detailed code examples, refer to these files: - Create ScriptableObjects, modify with SerializedObject - **Scene operations**: See [references/scene-operations.md](references/scene-operations.md) - Create/modify GameObjects, set parents, wire references, load scenes +- **Batch operations**: See [references/batch-operations.md](references/batch-operations.md) + - Bulk modify objects, batch add/remove components, rename, layer/tag/material replacement +- **Cleanup operations**: See [references/cleanup-operations.md](references/cleanup-operations.md) + - Detect broken scripts, missing references, unused materials, empty GameObjects +- **Undo operations**: See [references/undo-operations.md](references/undo-operations.md) + - Undo-aware operations: RecordObject, AddComponent, SetParent, grouping +- **Selection operations**: See [references/selection-operations.md](references/selection-operations.md) + - Get/set selection, multi-select, filter by type/editability + +## Workflow + +1. Identify the user's intent from $ARGUMENTS +2. Select and read the relevant reference file(s) from the list above +3. Construct C# code based on the reference examples +4. Execute via `uloop execute-dynamic-code --code ''` +5. If execution fails, adjust code and retry +6. Report the execution result From 21f3be0e7526229bcaf5e970eafb215886f1e08f Mon Sep 17 00:00:00 2001 From: hatayama Date: Fri, 6 Mar 2026 22:25:51 +0900 Subject: [PATCH 02/13] =?UTF-8?q?prefab-operations.md=E3=81=ABSerializedFi?= =?UTF-8?q?eld=E5=8F=82=E7=85=A7=E9=85=8D=E7=B7=9A=E3=81=AE=E3=83=AA?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=83=AC=E3=83=B3=E3=82=B9=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prefab内MonoBehaviourのSerializedFieldに別アセットの参照を設定する パターンが欠落していたため、2つのユースケースを追加: - 単一参照の配線(EditPrefabContentsScope + SerializedObject) - 複数参照の一括配線(Material, AudioClip等) --- .../references/prefab-operations.md | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/.claude/skills/uloop-execute-dynamic-code/references/prefab-operations.md b/.claude/skills/uloop-execute-dynamic-code/references/prefab-operations.md index 7e9a8d25f..1e85ca2fa 100644 --- a/.claude/skills/uloop-execute-dynamic-code/references/prefab-operations.md +++ b/.claude/skills/uloop-execute-dynamic-code/references/prefab-operations.md @@ -82,6 +82,78 @@ using (PrefabUtility.EditPrefabContentsScope scope = new PrefabUtility.EditPrefa return "Modified prefab properties"; ``` +## Wire SerializedField Reference in Prefab + +```csharp +using UnityEditor; + +string prefabPath = "Assets/Prefabs/Player.prefab"; +string weaponPrefabPath = "Assets/Prefabs/Weapon.prefab"; +GameObject weaponPrefab = AssetDatabase.LoadAssetAtPath(weaponPrefabPath); +if (weaponPrefab == null) +{ + return $"Asset not found at {weaponPrefabPath}"; +} + +using (PrefabUtility.EditPrefabContentsScope scope = new PrefabUtility.EditPrefabContentsScope(prefabPath)) +{ + GameObject root = scope.prefabContentsRoot; + MonoBehaviour script = root.GetComponent("PlayerController") as MonoBehaviour; + if (script == null) + { + return "PlayerController not found on prefab root"; + } + + SerializedObject so = new SerializedObject(script); + SerializedProperty prop = so.FindProperty("weaponPrefab"); + if (prop == null) + { + return "Property 'weaponPrefab' not found"; + } + + prop.objectReferenceValue = weaponPrefab; + so.ApplyModifiedProperties(); +} +return "Wired weaponPrefab reference in Player prefab"; +``` + +## Wire Multiple References in Prefab + +```csharp +using UnityEditor; + +string prefabPath = "Assets/Prefabs/Enemy.prefab"; + +using (PrefabUtility.EditPrefabContentsScope scope = new PrefabUtility.EditPrefabContentsScope(prefabPath)) +{ + GameObject root = scope.prefabContentsRoot; + MonoBehaviour script = root.GetComponent("EnemyController") as MonoBehaviour; + if (script == null) + { + return "EnemyController not found"; + } + + SerializedObject so = new SerializedObject(script); + + SerializedProperty matProp = so.FindProperty("bodyMaterial"); + Material mat = AssetDatabase.LoadAssetAtPath("Assets/Materials/EnemyBody.mat"); + if (matProp != null && mat != null) + { + matProp.objectReferenceValue = mat; + } + + SerializedProperty clipProp = so.FindProperty("deathSound"); + AudioClip clip = AssetDatabase.LoadAssetAtPath("Assets/Audio/Death.wav"); + if (clipProp != null && clip != null) + { + clipProp.objectReferenceValue = clip; + } + + so.ApplyModifiedProperties(); +} +return "Wired multiple references in Enemy prefab"; +``` + ## Find All Prefab Instances in Scene ```csharp From feb94bfafb96d1de4bfb7e8679449270eb90eb14 Mon Sep 17 00:00:00 2001 From: hatayama Date: Fri, 6 Mar 2026 22:30:45 +0900 Subject: [PATCH 03/13] Normalize minimal .meta files to Unity canonical format These .meta files had only fileFormatVersion and guid (2 lines, no trailing newline). Unity expands them to full MonoImporter format on every AssetDatabase.Refresh, causing spurious diffs. Committing the normalized form prevents recurring changes. --- .../CompilationDiagnosticMessageParserTests.cs.meta | 11 ++++++++++- .../Editor/DomainReloadDetectionServiceTests.cs.meta | 11 ++++++++++- .../Editor/DomainReloadStateRegistryTests.cs.meta | 11 ++++++++++- .../DynamicCodeExecutorFactoryTests.cs.meta | 11 ++++++++++- .../Config/McpEditorDomainReloadStateProvider.cs.meta | 11 ++++++++++- .../RoslynDynamicCompilationServiceFactory.cs.meta | 11 ++++++++++- ...oslynDynamicCompilationServiceRegistration.cs.meta | 11 ++++++++++- .../Composition/DomainReloadStateRegistry.cs.meta | 11 ++++++++++- .../DynamicCompilationServiceRegistry.cs.meta | 11 ++++++++++- .../CompilationDiagnosticMessageParser.cs.meta | 11 ++++++++++- .../Interfaces/IDomainReloadStateProvider.cs.meta | 11 ++++++++++- .../Interfaces/IDynamicCompilationService.cs.meta | 11 ++++++++++- .../IDynamicCompilationServiceFactory.cs.meta | 11 ++++++++++- 13 files changed, 130 insertions(+), 13 deletions(-) diff --git a/Assets/Tests/Editor/CompilationDiagnosticMessageParserTests.cs.meta b/Assets/Tests/Editor/CompilationDiagnosticMessageParserTests.cs.meta index a72be036a..7931b0a30 100644 --- a/Assets/Tests/Editor/CompilationDiagnosticMessageParserTests.cs.meta +++ b/Assets/Tests/Editor/CompilationDiagnosticMessageParserTests.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: ac4cdb9f475134600890c5f7ddba825c \ No newline at end of file +guid: ac4cdb9f475134600890c5f7ddba825c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests/Editor/DomainReloadDetectionServiceTests.cs.meta b/Assets/Tests/Editor/DomainReloadDetectionServiceTests.cs.meta index bd1555186..b296f92f8 100644 --- a/Assets/Tests/Editor/DomainReloadDetectionServiceTests.cs.meta +++ b/Assets/Tests/Editor/DomainReloadDetectionServiceTests.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 44879f4479ea44353b4c1eb8db953b12 \ No newline at end of file +guid: 44879f4479ea44353b4c1eb8db953b12 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests/Editor/DomainReloadStateRegistryTests.cs.meta b/Assets/Tests/Editor/DomainReloadStateRegistryTests.cs.meta index e4aba5c1f..000a1f1c6 100644 --- a/Assets/Tests/Editor/DomainReloadStateRegistryTests.cs.meta +++ b/Assets/Tests/Editor/DomainReloadStateRegistryTests.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: a727c26d178d24ca3b803a08b95c8c4a \ No newline at end of file +guid: a727c26d178d24ca3b803a08b95c8c4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests/Editor/DynamicCodeToolTests/DynamicCodeExecutorFactoryTests.cs.meta b/Assets/Tests/Editor/DynamicCodeToolTests/DynamicCodeExecutorFactoryTests.cs.meta index 7e1890c4b..e532e0510 100644 --- a/Assets/Tests/Editor/DynamicCodeToolTests/DynamicCodeExecutorFactoryTests.cs.meta +++ b/Assets/Tests/Editor/DynamicCodeToolTests/DynamicCodeExecutorFactoryTests.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 627b67c7cb2774cb8ae8bc0e649ccc4e \ No newline at end of file +guid: 627b67c7cb2774cb8ae8bc0e649ccc4e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Editor/Config/McpEditorDomainReloadStateProvider.cs.meta b/Packages/src/Editor/Config/McpEditorDomainReloadStateProvider.cs.meta index e750b3631..cf1476534 100644 --- a/Packages/src/Editor/Config/McpEditorDomainReloadStateProvider.cs.meta +++ b/Packages/src/Editor/Config/McpEditorDomainReloadStateProvider.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 8134fd2d31bde432e9b69459511ee909 \ No newline at end of file +guid: 8134fd2d31bde432e9b69459511ee909 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Editor/Roslyn/Compilation/RoslynDynamicCompilationServiceFactory.cs.meta b/Packages/src/Editor/Roslyn/Compilation/RoslynDynamicCompilationServiceFactory.cs.meta index c8129bb87..8d3c518a5 100644 --- a/Packages/src/Editor/Roslyn/Compilation/RoslynDynamicCompilationServiceFactory.cs.meta +++ b/Packages/src/Editor/Roslyn/Compilation/RoslynDynamicCompilationServiceFactory.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 44ad3e1fbfaa047c0a63c7d167738e36 \ No newline at end of file +guid: 44ad3e1fbfaa047c0a63c7d167738e36 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Editor/Roslyn/Compilation/RoslynDynamicCompilationServiceRegistration.cs.meta b/Packages/src/Editor/Roslyn/Compilation/RoslynDynamicCompilationServiceRegistration.cs.meta index 8f6c1912d..9f857ffb1 100644 --- a/Packages/src/Editor/Roslyn/Compilation/RoslynDynamicCompilationServiceRegistration.cs.meta +++ b/Packages/src/Editor/Roslyn/Compilation/RoslynDynamicCompilationServiceRegistration.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 8ed88db7432a04951af321c2b169ac77 \ No newline at end of file +guid: 8ed88db7432a04951af321c2b169ac77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Editor/Shared/Composition/DomainReloadStateRegistry.cs.meta b/Packages/src/Editor/Shared/Composition/DomainReloadStateRegistry.cs.meta index 87a75147f..a65baea69 100644 --- a/Packages/src/Editor/Shared/Composition/DomainReloadStateRegistry.cs.meta +++ b/Packages/src/Editor/Shared/Composition/DomainReloadStateRegistry.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 16f03c71027d5433cb920e1830289b86 \ No newline at end of file +guid: 16f03c71027d5433cb920e1830289b86 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Editor/Shared/Composition/DynamicCompilationServiceRegistry.cs.meta b/Packages/src/Editor/Shared/Composition/DynamicCompilationServiceRegistry.cs.meta index e5b5a3d2a..b956e9991 100644 --- a/Packages/src/Editor/Shared/Composition/DynamicCompilationServiceRegistry.cs.meta +++ b/Packages/src/Editor/Shared/Composition/DynamicCompilationServiceRegistry.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: ed1454bd9d3934dea8704fd28061c595 \ No newline at end of file +guid: ed1454bd9d3934dea8704fd28061c595 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Editor/Shared/Diagnostics/CompilationDiagnosticMessageParser.cs.meta b/Packages/src/Editor/Shared/Diagnostics/CompilationDiagnosticMessageParser.cs.meta index 884763fb9..48bb5eea6 100644 --- a/Packages/src/Editor/Shared/Diagnostics/CompilationDiagnosticMessageParser.cs.meta +++ b/Packages/src/Editor/Shared/Diagnostics/CompilationDiagnosticMessageParser.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: c2284b0ac895440efaea20245f59aec3 \ No newline at end of file +guid: c2284b0ac895440efaea20245f59aec3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Editor/Shared/Interfaces/IDomainReloadStateProvider.cs.meta b/Packages/src/Editor/Shared/Interfaces/IDomainReloadStateProvider.cs.meta index 722f79da1..2f5262e22 100644 --- a/Packages/src/Editor/Shared/Interfaces/IDomainReloadStateProvider.cs.meta +++ b/Packages/src/Editor/Shared/Interfaces/IDomainReloadStateProvider.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 36b0d8ce58cd14305b7904e3e1f12aaf \ No newline at end of file +guid: 36b0d8ce58cd14305b7904e3e1f12aaf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Editor/Shared/Interfaces/IDynamicCompilationService.cs.meta b/Packages/src/Editor/Shared/Interfaces/IDynamicCompilationService.cs.meta index bfddcfa9d..8dcd8b355 100644 --- a/Packages/src/Editor/Shared/Interfaces/IDynamicCompilationService.cs.meta +++ b/Packages/src/Editor/Shared/Interfaces/IDynamicCompilationService.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 4d52a22eb1364461296f82cd4ccaca9e \ No newline at end of file +guid: 4d52a22eb1364461296f82cd4ccaca9e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Editor/Shared/Interfaces/IDynamicCompilationServiceFactory.cs.meta b/Packages/src/Editor/Shared/Interfaces/IDynamicCompilationServiceFactory.cs.meta index 7b107579d..45e35a8df 100644 --- a/Packages/src/Editor/Shared/Interfaces/IDynamicCompilationServiceFactory.cs.meta +++ b/Packages/src/Editor/Shared/Interfaces/IDynamicCompilationServiceFactory.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 82de15f662b864f2f8ba18aa82b83a5b \ No newline at end of file +guid: 82de15f662b864f2f8ba18aa82b83a5b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 5b702f051d843d90de70aa64f7d71ceada9449db Mon Sep 17 00:00:00 2001 From: hatayama Date: Fri, 6 Mar 2026 22:36:47 +0900 Subject: [PATCH 04/13] Add PlayMode automation reference for execute-dynamic-code skill Add playmode-automation.md with 11 runtime automation examples: UI button clicking (by path, name search, TMP label), Physics and EventSystem raycasting, method invocation via reflection, field manipulation, animation triggers, and scene-wide button listing. These patterns enable automated UI testing and runtime manipulation during Play mode via execute-dynamic-code. --- .../uloop-execute-dynamic-code/SKILL.md | 2 + .../references/playmode-automation.md | 188 ++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 .claude/skills/uloop-execute-dynamic-code/references/playmode-automation.md diff --git a/.claude/skills/uloop-execute-dynamic-code/SKILL.md b/.claude/skills/uloop-execute-dynamic-code/SKILL.md index 8cb7c8cf7..4d0852d3d 100644 --- a/.claude/skills/uloop-execute-dynamic-code/SKILL.md +++ b/.claude/skills/uloop-execute-dynamic-code/SKILL.md @@ -114,6 +114,8 @@ For detailed code examples, refer to these files: - Undo-aware operations: RecordObject, AddComponent, SetParent, grouping - **Selection operations**: See [references/selection-operations.md](references/selection-operations.md) - Get/set selection, multi-select, filter by type/editability +- **PlayMode automation**: See [references/playmode-automation.md](references/playmode-automation.md) + - Click UI buttons, raycast interaction, invoke methods, set fields at runtime ## Workflow diff --git a/.claude/skills/uloop-execute-dynamic-code/references/playmode-automation.md b/.claude/skills/uloop-execute-dynamic-code/references/playmode-automation.md new file mode 100644 index 000000000..bbb54f9d8 --- /dev/null +++ b/.claude/skills/uloop-execute-dynamic-code/references/playmode-automation.md @@ -0,0 +1,188 @@ +# PlayMode Automation + +Code examples for runtime automation during Play mode using `execute-dynamic-code`. +These examples manipulate live scene objects while the game is running. + +## Click UI Button by Path + +```csharp +using UnityEngine.UI; + +Button btn = GameObject.Find("Canvas/StartButton")?.GetComponent