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
View on GitHubakiojin/unity-mcp-server
unity-mcp-server
.claude-plugin/plugins/unity-mcp-server/skills/unity-development/SKILL.md
January 21, 2026
Select agents to install to:
npx add-skill https://github.com/akiojin/unity-mcp-server/blob/main/.claude-plugin/plugins/unity-mcp-server/skills/unity-development/SKILL.md -a claude-code --skill unity-developmentInstallation paths:
.claude/skills/unity-development/# Unity Development Guide
A comprehensive guide for Unity development. This skill serves as **always-referenced parent skill**, providing common patterns and tool selection guidance.
## Architecture Patterns
### Fail-Fast Principle
**Do not write null checks. Use objects directly when their existence is assumed.**
```csharp
// 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**:
- Null check after `GetComponent<T>()`
- Null check after `Find*()`
- Null check after `[Inject]`
### No GetComponent in Update
**GetComponent every frame causes GC allocation and performance degradation. Cache in Awake.**
```csharp
// 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;
}
```
### UniTask Patterns
**Use UniTask instead of coroutines. async void is forbidden.**
```csharp
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**:
- Use `destroyCancellationToken` for auto-cancel on GameObject destruction
- `UniTask.Delay` > `Task.Delay` (zero allocation)
- `UniTask.WhenAll` for parallel execution
### VContainer DI
**Use VContainer for dependency injection. Constructor injection recommended.**
```csharp
// Interface definition
public interface IPla