Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 196 additions & 0 deletions Unity/.codex/skills/funplay-unity-mcp-workflow/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
---
name: funplay-unity-mcp-workflow
description: Efficient workflow for using Unity MCP to edit, import, compile, inspect, and test Unity projects.
platform: codex
---
<!-- Funplay Unity MCP managed project skills -->

# Unity MCP Workflow

Use this skill when Codex or another AI agent is working in a Unity project and needs to verify code, prefabs, UI, Play Mode behavior, screenshots, scene hierarchy, console logs, domain reloads, or MCP connection issues.

## Operating Loop

1. Establish context.
- Confirm the Unity project root and active scene.
- Check that Unity MCP is reachable before assuming Editor state.
- Inspect hierarchy, prefab paths, selected objects, and relevant component references through MCP.
- If the user names an object, verify the real Unity object path before editing.
2. Choose the edit surface.
- Edit source files with normal repo tools, then trigger Unity recompilation.
- Edit scene objects through Unity APIs, mark the scene dirty, and save the scene.
- Edit prefab assets with `PrefabUtility.LoadPrefabContents`, `PrefabUtility.SaveAsPrefabAsset`, and `PrefabUtility.UnloadPrefabContents`.
- If the user is looking at an open scene instance, update the visible scene instance as well as the prefab asset when appropriate.
3. Execute changes.
- Prefer one well-guarded `execute_code` batch over many fragile UI clicks.
- Use null guards for every object lookup and return explicit missing-path messages.
- Return concise before/after values from snippets.
- Save only the assets or scenes intentionally modified.
4. Validate.
- Read back the changed objects through MCP.
- For file edits, call `request_recompile`, then `wait_for_compilation`, then inspect console or compilation errors.
- For runtime behavior, enter Play Mode or inspect live objects when needed.
- Report exactly what was verified and what still requires device, store, network, or manual validation.

## Tool Exposure

- With the default `core` profile, rely on the focused workflow tools: `execute_code`, recompilation, Play Mode control, hierarchy, console logs, screenshots, input simulation, and performance inspection.
- With the default `full` profile, prefer specific MCP tools for simple scene, asset, GameObject, component, prefab, camera, UI, package, animation, file, or visual-feedback operations.
- If Tool Exposure is customized and a named tool is unavailable, adapt to the exposed tool list and report which expected tool is missing.

## MCP Call Pattern

If native MCP tools are not directly available, probe the local HTTP endpoint:

```bash
curl -sS -m 1 -X POST http://127.0.0.1:8765/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

For multi-line `execute_code` calls over curl, generate JSON with a real encoder instead of hand-escaping C#:

```bash
node - <<'NODE'
const code = String.raw`
using UnityEngine;

public class InspectSomething
{
public static string Run()
{
var obj = GameObject.Find("PracticeInGameUiRoot");
return obj != null ? obj.name : "not found";
}
}
`;
const payload = {
jsonrpc: "2.0",
id: 1,
method: "tools/call",
params: { name: "execute_code", arguments: { code } }
};
process.stdout.write(JSON.stringify(payload));
NODE
```

## Unity C# Patterns

Use fully qualified types if the snippet environment or injected project code makes `using` statements unreliable:

```csharp
var root = UnityEngine.GameObject.Find("PracticeInGameUiRoot");
var rect = root.GetComponent<UnityEngine.RectTransform>();
```

Use Unity null semantics for `UnityEngine.Object` references:

```csharp
if (image == null)
{
return "Image missing";
}
```

For prefab edits:

```csharp
var path = "Assets/MyGame/UI/Prefabs/PF_PracticeInGameUiRoot.prefab";
var prefab = UnityEditor.PrefabUtility.LoadPrefabContents(path);
try
{
var target = prefab.transform.Find("SafeArea/SwingCancelZone");
if (target == null)
{
return "SwingCancelZone not found in prefab";
}

var rect = target.GetComponent<UnityEngine.RectTransform>();
var before = rect.anchoredPosition;
rect.anchoredPosition = new UnityEngine.Vector2(-76f, 448f);

UnityEditor.EditorUtility.SetDirty(rect);
UnityEditor.PrefabUtility.SaveAsPrefabAsset(prefab, path);
UnityEditor.AssetDatabase.SaveAssets();
return "Prefab saved: pos " + before + " -> " + rect.anchoredPosition;
}
finally
{
UnityEditor.PrefabUtility.UnloadPrefabContents(prefab);
}
```

For scene edits:

```csharp
var obj = UnityEngine.GameObject.Find("PracticeInGameUiRoot/SafeArea/SwingCancelZone");
if (obj == null)
{
return "Scene object not found";
}

var rect = obj.GetComponent<UnityEngine.RectTransform>();
var before = rect.sizeDelta;
UnityEditor.Undo.RecordObject(rect, "Update cancel zone");
rect.sizeDelta = new UnityEngine.Vector2(220f, 116f);
UnityEditor.EditorUtility.SetDirty(rect);
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(obj.scene);
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(obj.scene);
return "Scene saved: size " + before + " -> " + rect.sizeDelta;
```

## Recompile And Reload

After external C# or asset file edits:

1. If Unity is in Play Mode, call `exit_play_mode` first - `request_recompile` is rejected during play because Unity does not run script compilation or domain reloads while playing.
2. Call `request_recompile`.
3. Call `wait_for_compilation`.
4. Read console or compilation errors before continuing.
5. If a domain reload drops the request, call `get_reload_recovery_status` when available, re-scan the MCP endpoint if needed, then continue from `wait_for_compilation`.

Do not treat a disconnected request as a successful compile.

After `enter_play_mode`, the HTTP server is briefly unreachable while Unity reloads the domain. Before issuing the next tool call, poll a cheap endpoint such as `tools/list` (or `get_reload_recovery_status` if exposed) until you get a response - do not assume the connection survives the Play Mode transition.

## Verification Checklist

Use readback snippets that print exact values, not only `success`:

```csharp
var all = UnityEngine.Resources.FindObjectsOfTypeAll<UnityEngine.Transform>();
UnityEngine.Transform target = null;
for (int i = 0; i < all.Length; i++)
{
if (all[i].name == "SwingCancelZone")
{
target = all[i];
break;
}
}

if (target == null)
{
return "SwingCancelZone not found";
}

var rect = target.GetComponent<UnityEngine.RectTransform>();
return "path=" + target.name + "; pos=" + rect.anchoredPosition + "; size=" + rect.sizeDelta;
```

For UI work, verify prefab or scene hierarchy, sprite references, anchors, sorting order, active state, text fit, and button listeners. A populated `Content` hierarchy does not prove the user can see the UI.

For gameplay or network work, verify object identity, ownership, live instance existence, transform values, animation state, visibility, and whether client-side filters are discarding valid data.

## Failure Handling

- If MCP is unreachable, say so and fall back only to safe filesystem inspection or code edits. Do not claim scene, prefab, or runtime verification without Unity readback.
- If an object lookup fails, inspect hierarchy and prefab contents instead of inventing a path.
- If multiple matching objects exist, print their paths and choose the one matching the user-visible UI or current scene.
- If compile errors appear after a change, fix them before Play Mode validation.
- When Unity and text files disagree for serialized scene or prefab state, trust Unity readback and inspect the asset path.

## Metadata

- Original skill id: `unity-mcp-workflow`
- Source repository: `https://github.com/FunplayAI/funplay-unity-mcp`
6 changes: 6 additions & 0 deletions Unity/.funplay/skills/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"platforms": [
"codex"
],
"optionalSkills": []
}
34 changes: 34 additions & 0 deletions Unity/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!-- Funplay Unity MCP managed project skills -->

# Funplay Unity MCP Project Guidance

This file is managed by Funplay MCP for Unity.

## Installed project skills

- `funplay-unity-mcp-workflow` - Efficient workflow for using Unity MCP to edit, import, compile, inspect, and test Unity projects.

## Codex workflow rules

- Prefer project-local Funplay skills under `.codex/skills/`.
- Use `execute_code` as the primary Unity automation tool. For new snippets, implement `IFunplayCommand` and use `ctx.RegisterObjectCreation` / `RegisterObjectModification` / `DestroyObject` so changes participate in Undo automatically.
- Inspect Unity objects through MCP before changing user-named scene or prefab targets. Carry the returned `instanceId` into follow-up calls (`find_method=by_id`) instead of re-resolving by name.
- Tool returns are structured JSON (`{success, message, data}` / `{success: false, code, error, data}`). Branch on `code`, not free-form text.
- Set component fields with `set_component_property(ies)` - it picks up `[SerializeField] private` fields and accepts Object references as `{"fileID": <instanceId>}` or `{"assetPath": "Assets/..."}`.
- Read editor state through dedicated tools (`get_selection`, `get_prefab_stage`, `get_tags`, `get_layers`, `get_build_settings`); use `execute_menu_item` before falling back to ad-hoc `execute_code`.
- Save only the scene or prefab assets intentionally modified, then read back exact values.
- With default `core` exposure, use the focused workflow tools. With default `full` exposure, prefer specific MCP tools for simple editor operations.
- `execute_code` refreshes the asset database and waits for compilation before running. For other tools that depend on freshly compiled code, still call `request_recompile` after external script edits.
- `request_recompile` is rejected while Unity is in Play Mode. Call `exit_play_mode` first, then retry.
- After `enter_play_mode`, the HTTP server briefly drops while Unity reloads the domain. Poll `tools/list` or `get_reload_recovery_status` until it responds again before issuing the next tool call.
- If recompilation triggers a domain reload, call `get_reload_recovery_status`.
- Avoid changing `Library/`, `Temp/`, `Logs/`, or `obj/`.

## Project

- Project root: `D:\Projects\Second-Spawn\Unity`
- Product name: `Second Spawn`

## Notes

- Re-run `Funplay > Project Skills` after changing selected skills or platforms.
1 change: 1 addition & 0 deletions Unity/Packages/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"dependencies": {
"com.coplaydev.unity-mcp": "https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main",
"com.gamebooom.unity.mcp": "https://github.com/FunplayAI/funplay-unity-mcp.git",
"com.unity.ai.assistant": "2.8.0-pre.1",
"com.unity.ai.inference": "2.6.1",
"com.unity.ai.navigation": "2.0.12",
Expand Down
10 changes: 10 additions & 0 deletions Unity/Packages/packages-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@
},
"hash": "b92c05a25820cfc9f59ce4094eb46aaec8632ea2"
},
"com.gamebooom.unity.mcp": {
"version": "https://github.com/FunplayAI/funplay-unity-mcp.git",
"depth": 0,
"source": "git",
"dependencies": {
"com.unity.nuget.newtonsoft-json": "3.2.1",
"com.unity.inputsystem": "1.7.0"
},
"hash": "b600f4e2b1d3a80a2558f4ce804055d120877952"
},
"com.unity.2d.sprite": {
"version": "1.0.0",
"depth": 1,
Expand Down
Loading