Comprehensive guide for Unity development. Provides architecture patterns, MCP tool selection, and composite task workflows. Parent skill always referenced for Unity-related tasks. See child skills for detailed implementation. Use when: Unity development in general, C# editing, scene operations, UI implementation, asset management, PlayMode testing
/plugin marketplace add akiojin/unity-mcp-server/plugin install unity-mcp-server@unity-mcp-serverThis skill is limited to using the following tools:
A comprehensive guide for Unity development. This skill serves as always-referenced parent skill, providing common patterns and tool selection guidance.
Do not write null checks. Use objects directly when their existence is assumed.
// NG: Forbidden pattern
if (component != null) { component.DoSomething(); }
if (gameObject != null) { gameObject.SetActive(false); }
if (service != null) { service.Execute(); }
// OK: Correct pattern - direct usage
GetComponent<Rigidbody>().velocity = Vector3.zero;
GameService.Initialize();
target.position = Vector3.zero;
Applies to:
GetComponent<T>()Find*()[Inject]GetComponent every frame causes GC allocation and performance degradation. Cache in Awake.
// NG: GC allocation every frame
void Update()
{
GetComponent<Rigidbody>().velocity = input;
}
// OK: Cache in Awake
private Rigidbody _rb;
void Awake()
{
_rb = GetComponent<Rigidbody>();
}
void Update()
{
_rb.velocity = input;
}
Use UniTask instead of coroutines. async void is forbidden.
using Cysharp.Threading.Tasks;
// NG: async void
async void Start()
{
await DoWorkAsync();
}
// OK: UniTaskVoid + destroyCancellationToken
async UniTaskVoid Start()
{
await DoWorkAsync(destroyCancellationToken);
}
// OK: When return value is needed
async UniTask<int> CalculateAsync(CancellationToken ct)
{
await UniTask.Delay(1000, cancellationToken: ct);
return 42;
}
Best Practices:
destroyCancellationToken for auto-cancel on GameObject destructionUniTask.Delay > Task.Delay (zero allocation)UniTask.WhenAll for parallel executionUse VContainer for dependency injection. Constructor injection recommended.
// Interface definition
public interface IPlayerService
{
void Initialize();
}
// Implementation class
public class PlayerService : IPlayerService
{
public void Initialize() { /* ... */ }
}
// Consumer (MonoBehaviour)
public class GameManager : MonoBehaviour
{
[Inject] private readonly IPlayerService _playerService;
void Start()
{
_playerService.Initialize();
}
}
// LifetimeScope configuration
public class GameLifetimeScope : LifetimeScope
{
protected override void Configure(IContainerBuilder builder)
{
builder.Register<IPlayerService, PlayerService>(Lifetime.Singleton);
builder.RegisterComponentInHierarchy<GameManager>();
}
}
Lifetime Selection:
Lifetime.Singleton - One instance for entire appLifetime.Scoped - One instance per sceneLifetime.Transient - New instance each time| Tool | Purpose | Usage Condition |
|---|---|---|
edit_snippet | Lightweight edit | Diff within 80 characters |
edit_structured | Structured edit | Method body replacement, member addition |
get_symbols | Symbol list | Required before editing |
find_symbol | Symbol search | Find symbol by name |
find_refs | Reference search | Before refactoring |
read | Read code | Check file contents |
search | Pattern search | Regex search |
create_class | Create class | New file |
rename_symbol | Rename | Project-wide |
remove_symbol | Remove symbol | Delete unused code |
| Tool | Purpose |
|---|---|
get_hierarchy | Get hierarchy |
create_gameobject | Create GameObject |
modify_gameobject | Modify GameObject |
delete_gameobject | Delete GameObject |
find_gameobject | Find GameObject |
add_component | Add component |
modify_component | Modify component |
remove_component | Remove component |
list_components | List components |
| Tool | Purpose |
|---|---|
create_prefab | Create prefab |
modify_prefab | Modify prefab |
instantiate_prefab | Instantiate prefab |
create_material | Create material |
modify_material | Modify material |
manage_asset_database | Asset operations |
addressables_manage | Addressables management |
| Tool | Purpose |
|---|---|
play_game | Start PlayMode |
stop_game | Stop PlayMode |
pause_game | Pause |
input_keyboard | Keyboard input |
input_mouse | Mouse input |
input_gamepad | Gamepad input |
capture_screenshot | Screenshot |
run_tests | Run tests |
| System | Purpose | Detail Skill |
|---|---|---|
| uGUI | Game UI (Canvas/EventSystem) | unity-game-ugui-design |
| UI Toolkit | Modern UI (Runtime/Editor) | unity-game-ui-toolkit-design |
| IMGUI | Editor extensions only | unity-editor-imgui-design |
Required operations: UI creation + Scene management + C# script
// 1. Create button GameObject
mcp__unity-mcp-server__create_gameobject({
name: "StartButton",
parentPath: "/Canvas"
})
// 2. Add Button component
mcp__unity-mcp-server__add_component({
gameObjectPath: "/Canvas/StartButton",
componentType: "Button"
})
// 3. Create click handler script
mcp__unity-mcp-server__create_class({
path: "Assets/Scripts/UI/StartButtonHandler.cs",
className: "StartButtonHandler",
baseType: "MonoBehaviour",
namespace: "Game.UI"
})
// 4. Add OnClick implementation
mcp__unity-mcp-server__edit_structured({
path: "Assets/Scripts/UI/StartButtonHandler.cs",
symbolName: "StartButtonHandler",
operation: "insert_after",
newText: `
public void OnStartClicked()
{
SceneManager.LoadScene("GameScene");
}
`
})
Required operations: GameObject + Components + C# script + Prefab
// 1. Create enemy GameObject
mcp__unity-mcp-server__create_gameobject({
name: "Enemy",
primitiveType: "capsule",
position: { x: 0, y: 1, z: 0 }
})
// 2. Add components
mcp__unity-mcp-server__add_component({
gameObjectPath: "/Enemy",
componentType: "Rigidbody"
})
// 3. Create enemy script
mcp__unity-mcp-server__create_class({
path: "Assets/Scripts/Enemies/EnemyController.cs",
className: "EnemyController",
baseType: "MonoBehaviour"
})
// 4. Add AI implementation
mcp__unity-mcp-server__edit_structured({
path: "Assets/Scripts/Enemies/EnemyController.cs",
symbolName: "EnemyController",
operation: "insert_after",
newText: `
[SerializeField] private float _speed = 3f;
private Transform _target;
void Update()
{
if (_target != null)
transform.position = Vector3.MoveTowards(
transform.position,
_target.position,
_speed * Time.deltaTime
);
}
`
})
// 5. Convert to prefab
mcp__unity-mcp-server__create_prefab({
gameObjectPath: "/Enemy",
prefabPath: "Assets/Prefabs/Enemies/Enemy.prefab"
})
Required operations: Test creation + PlayMode control + Input simulation
// 1. Create test class
mcp__unity-mcp-server__create_class({
path: "Assets/Tests/PlayMode/PlayerMovementTests.cs",
className: "PlayerMovementTests",
namespace: "Tests.PlayMode",
usings: "NUnit.Framework,UnityEngine.TestTools,System.Collections"
})
// 2. Add PlayMode test implementation
mcp__unity-mcp-server__edit_structured({
path: "Assets/Tests/PlayMode/PlayerMovementTests.cs",
symbolName: "PlayerMovementTests",
operation: "insert_after",
newText: `
[UnityTest]
public IEnumerator Player_MovesForward_WhenWPressed()
{
var player = Object.FindObjectOfType<PlayerController>();
var startPos = player.transform.position;
yield return null;
// Simulate W key input
// Use input_keyboard tool during test execution
yield return new WaitForSeconds(0.5f);
Assert.Greater(player.transform.position.z, startPos.z);
}
`
})
// 3. Run tests
mcp__unity-mcp-server__run_tests({
testMode: "PlayMode",
filter: "PlayerMovementTests"
})
Refer to the following child skills when detailed implementation patterns are needed:
| Skill | Purpose | When to Reference |
|---|---|---|
unity-csharp-editing | C# editing, TDD, refactoring | During code editing |
unity-scene-management | Scene & GameObject operations | During scene construction |
unity-asset-management | Prefabs, materials, Addressables | During asset management |
unity-playmode-testing | PlayMode, input simulation | During test execution |
unity-game-ugui-design | uGUI (Canvas/EventSystem) | During game UI implementation |
unity-game-ui-toolkit-design | UI Toolkit (Runtime) | During modern UI implementation |
unity-editor-imgui-design | IMGUI (EditorWindow/Inspector) | During editor extension |
Unity Development Task
├─ Need code editing?
│ ├─ YES → edit_snippet / edit_structured
│ │ Details: unity-csharp-editing
│ └─ NO → Next
├─ Need scene/GameObject operations?
│ ├─ YES → create_gameobject / add_component
│ │ Details: unity-scene-management
│ └─ NO → Next
├─ Need asset operations?
│ ├─ YES → create_prefab / addressables_manage
│ │ Details: unity-asset-management
│ └─ NO → Next
├─ Need UI implementation?
│ ├─ Game UI → unity-game-ugui-design or unity-game-ui-toolkit-design
│ └─ Editor UI → unity-editor-imgui-design
└─ Need testing/verification?
└─ YES → play_game / run_tests
Details: unity-playmode-testing
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.