Supports Unity C# script editing, searching, and refactoring. Enables TDD cycle code editing, symbol navigation, reference searching, and structured editing. Use when: C# editing, script search, symbol search, refactoring, code indexing, class creation, method addition
/plugin marketplace add akiojin/unity-mcp-server/plugin install akiojin-unity-mcp-server-claude-plugin-plugins-unity-mcp-server@akiojin/unity-mcp-serverThis skill is limited to using the following tools:
A guide for efficient editing, searching, and refactoring of Unity C# scripts.
On first use or when the index is outdated, build the index first:
// Check index status
mcp__unity-mcp-server__get_index_status()
// Build index (first time only, may take a few minutes)
mcp__unity-mcp-server__build_index()
// Get symbol list in file
mcp__unity-mcp-server__get_symbols({
path: "Assets/Scripts/Player.cs"
})
// Get specific symbol details
mcp__unity-mcp-server__find_symbol({
name: "PlayerController",
kind: "class",
exact: true
})
// Read code
mcp__unity-mcp-server__read({
path: "Assets/Scripts/Player.cs",
startLine: 10,
endLine: 50
})
// Small changes (within 80 characters) → snippet
mcp__unity-mcp-server__edit_snippet({
path: "Assets/Scripts/Player.cs",
instructions: [{
operation: "replace",
anchor: { type: "text", target: "if (health < 0)" },
newText: "if (health <= 0)"
}]
})
// Large changes (method body) → structured
mcp__unity-mcp-server__edit_structured({
path: "Assets/Scripts/Player.cs",
symbolName: "PlayerController/TakeDamage",
operation: "replace_body",
newText: "{\n health -= damage;\n OnDamaged?.Invoke(damage);\n}"
})
unity-mcp-server provides a code index via built-in C# LSP. Output is 5x more compact than standard tools, optimizing LLM context.
| Tool | Purpose | Comparison |
|---|---|---|
find_symbol | Symbol search | 5x smaller output |
find_refs | Reference search | 3x smaller output |
search | Code search | Instant response |
Symbols are identified by hierarchical path within file:
// Simple class
PlayerController
// Nested member
PlayerController/TakeDamage
PlayerController/health
// Deep nesting
OuterClass/InnerClass/Method
Narrow search scope for better performance:
assets - Assets/ onlypackages - Packages/ onlyembedded - Embedded packages onlyall - All scope (default)The criterion for choosing an editing tool is "whether the diff is within 80 characters"
edit_snippetCondition: Diff within 80 characters, 1-2 line changes
// ✅ Remove null guard
{ operation: "delete", anchor: { type: "text", target: "if (x == null) return;\n" }}
// ✅ Minor condition fix
{ operation: "replace", anchor: { type: "text", target: "if (x > 10)" }, newText: "if (x > 20)" }
// ✅ Insert log statement
{ operation: "insert", anchor: { type: "text", target: "Process();\n" }, newText: "Debug.Log(\"Processing\");\n" }
edit_structuredCondition: Method body replacement, class member addition
// ✅ Replace method body
{
symbolName: "Player/Move",
operation: "replace_body",
newText: "{\n transform.position += direction * speed * Time.deltaTime;\n}"
}
// ✅ Add member to class
{
symbolName: "Player",
operation: "insert_after",
newText: "\n private float _jumpForce = 5f;\n"
}
Is the change within 80 characters?
├─ YES → edit_snippet
└─ NO → Is it entire method/property replacement?
├─ YES → edit_structured (replace_body)
└─ NO → Is it adding to class?
├─ YES → edit_structured (insert_after)
└─ NO → Split into multiple snippets
// Create test file
mcp__unity-mcp-server__create_class({
path: "Assets/Tests/PlayerTests.cs",
className: "PlayerTests",
namespace: "Tests",
usings: "NUnit.Framework,UnityEngine"
})
// Add test method
mcp__unity-mcp-server__edit_structured({
path: "Assets/Tests/PlayerTests.cs",
symbolName: "PlayerTests",
operation: "insert_after",
newText: `
[Test]
public void TakeDamage_ReducesHealth()
{
var player = new Player(100);
player.TakeDamage(30);
Assert.AreEqual(70, player.Health);
}
`
})
// Add implementation
mcp__unity-mcp-server__edit_structured({
path: "Assets/Scripts/Player.cs",
symbolName: "Player",
operation: "insert_after",
newText: `
public void TakeDamage(int damage)
{
Health -= damage;
}
`
})
// Check compilation state
mcp__unity-mcp-server__get_compilation_state({ includeMessages: true })
// Check impact before refactoring
mcp__unity-mcp-server__find_refs({
name: "TakeDamage",
container: "Player"
})
// 1. Create class file
mcp__unity-mcp-server__create_class({
path: "Assets/Scripts/Enemies/Enemy.cs",
className: "Enemy",
namespace: "Game.Enemies",
baseType: "MonoBehaviour",
usings: "UnityEngine,System"
})
// 2. Add fields and methods
mcp__unity-mcp-server__edit_structured({
path: "Assets/Scripts/Enemies/Enemy.cs",
symbolName: "Enemy",
operation: "insert_after",
newText: `
[SerializeField] private int _health = 100;
[SerializeField] private float _speed = 3f;
public int Health => _health;
public void TakeDamage(int damage)
{
_health = Mathf.Max(0, _health - damage);
if (_health == 0) Die();
}
private void Die()
{
Destroy(gameObject);
}
`
})
// 3. Update index
mcp__unity-mcp-server__update_index({
paths: ["Assets/Scripts/Enemies/Enemy.cs"]
})
// 1. Check impact
mcp__unity-mcp-server__find_refs({
name: "oldMethodName",
container: "ClassName",
scope: "all"
})
// 2. Execute rename (applies to entire project)
mcp__unity-mcp-server__rename_symbol({
relative: "Assets/Scripts/Player.cs",
namePath: "Player/oldMethodName",
newName: "newMethodName",
preview: true // Preview first
})
// 3. Apply if no issues
mcp__unity-mcp-server__rename_symbol({
relative: "Assets/Scripts/Player.cs",
namePath: "Player/oldMethodName",
newName: "newMethodName",
preview: false
})
// Pattern search (regex)
mcp__unity-mcp-server__search({
pattern: "GetComponent<.*>",
patternType: "regex",
scope: "assets",
returnMode: "snippets",
snippetContext: 2
})
// Search usages of specific class
mcp__unity-mcp-server__find_refs({
name: "PlayerController",
kind: "class",
scope: "all"
})
// Edit up to 10 locations at once
mcp__unity-mcp-server__edit_snippet({
path: "Assets/Scripts/GameManager.cs",
instructions: [
{ operation: "replace", anchor: { type: "text", target: "Debug.Log" }, newText: "Logger.Info" },
{ operation: "delete", anchor: { type: "text", target: "// TODO: remove\n" }},
{ operation: "insert", anchor: { type: "text", target: "void Start()\n {" }, newText: "\n Initialize();" }
]
})
For large or uncertain edits, verify with preview first:
// Validate in preview mode
mcp__unity-mcp-server__edit_structured({
path: "Assets/Scripts/Player.cs",
symbolName: "Player/Update",
operation: "replace_body",
newText: "{ /* new implementation */ }",
preview: true // Don't write to file
})
// Apply if no LSP diagnostic errors
mcp__unity-mcp-server__edit_structured({
// Same parameters with preview: false
})
// Confirm no references
mcp__unity-mcp-server__find_refs({
name: "UnusedMethod",
container: "Player"
})
// Remove if no references
mcp__unity-mcp-server__remove_symbol({
path: "Assets/Scripts/Player.cs",
namePath: "Player/UnusedMethod",
failOnReferences: true, // Error if referenced
apply: true
})
Problem: anchor_not_found error
// ❌ Incorrect whitespace/newlines
anchor: { type: "text", target: "if(x>10)" }
// ✅ Exact match with actual code
anchor: { type: "text", target: "if (x > 10)" }
Solution: Use read to check file contents, copy exact string including whitespace/newlines
Problem: diff exceeds 80 characters error
// ❌ Editing long code with snippet
{ operation: "replace", anchor: {...}, newText: "very long code..." }
// ✅ Use structured for method body replacement
{ symbolName: "Class/Method", operation: "replace_body", newText: "..." }
Problem: LSP timeout (60 seconds)
// ✅ Always check index status
mcp__unity-mcp-server__get_index_status()
// Build if coverage is low
mcp__unity-mcp-server__build_index()
Problem: anchor_not_unique error
// ❌ Anchor too generic
anchor: { type: "text", target: "return;" }
// ✅ Include context for uniqueness
anchor: { type: "text", target: " return health;\n }" }
Problem: Outdated symbol information returned after editing
// ✅ Always update index after editing
mcp__unity-mcp-server__update_index({
paths: ["Assets/Scripts/Player.cs"]
})
| Tool | Purpose | Key Parameters |
|---|---|---|
get_symbols | File symbol list | path |
find_symbol | Symbol search | name, kind, scope, exact |
find_refs | Reference search | name, container, scope |
read | Read code | path, startLine, endLine |
search | Pattern search | pattern, patternType, scope |
edit_snippet | Lightweight edit (within 80 chars) | path, instructions |
edit_structured | Structured edit | path, symbolName, operation, newText |
create_class | Create class | path, className, namespace, baseType |
rename_symbol | Rename | relative, namePath, newName |
remove_symbol | Remove symbol | path, namePath, failOnReferences |
get_index_status | Check index status | - |
build_index | Build index | - |
update_index | Update index | paths |
get_compilation_state | Compilation state | includeMessages |
Note: For architecture patterns (Fail-Fast, UniTask, VContainer, etc.), see parent skill
unity-development.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.