besty0728/unity-script
Create, read, and analyze C# scripts — create, read, replace, append, search, rename, move, and delete scripts, plus compile feedback. Use when authoring or editing C# code, searching across scripts, refactoring file layout, or checking compile errors, even if the user just says "写个脚本" or "改代码". 对 C# 脚本进行增删改查与分析(创建、读取、替换、追加、搜索、重命名、移动、删除脚本,以及编译反馈);当用户要编写或编辑 C# 代码、跨脚本搜索、重构文件布局、或检查编译错误时使用。
npx skills add https://github.com/Besty0728/Unity-Skills --skill unity-script
> BATCH-FIRST: Use script_create_batch when creating 2+ scripts.
> DESIGN-FIRST: Before creating gameplay scripts, actively consider coupling, performance, and maintainability. In an existing project, load ../project-scout/SKILL.md first. If the user is asking for architecture or refactoring advice, load ../architecture/SKILL.md and then ../patterns/SKILL.md, ../async/SKILL.md, ../inspector/SKILL.md, ../performance/SKILL.md, ../script-roles/SKILL.md, ../scene-contracts/SKILL.md, ../testability/SKILL.md, or ../scriptdesign/SKILL.md as needed.
script_read / script_list / script_find_in_file / script_get_info / script_get_compile_feedback,标 SkillMode.SemiAuto)直接执行;写型 skill(script_create / script_create_batch / script_replace / script_append / script_rename / script_move / script_delete,默认 SkillMode.FullAuto)需用户 grant,grant 后服务端一步执行返结果。script_create / script_create_batch / script_replace / script_append / script_delete 会触发 Domain Reload(且多标 RiskLevel=high),script_delete 同时是 Delete 操作 —— 这些 skill 在 Approval / Auto 下被 IsForbiddenInSemi 自动拦截,仅 Bypass 或 Allowlist 命中可执行。DO NOT (common hallucinations):
script_edit / script_update do not exist → use script_replace for find-and-replacescript_write does not exist → use script_create (new file) or script_replace (modify existing)scriptName parameter must NOT include .cs extensionRouting:
script_replace (find/replace) or script_append (add lines)script_readscript_get_compile_feedbackperception module's script_analyze| Single Object | Batch Version | Use Batch When |
|---------------|---------------|----------------|
| script_create | script_create_batch | Creating 2+ scripts |
No batch needed:
script_read - Read script contentscript_delete - Delete scriptscript_find_in_file - Search in scriptsscript_append - Append content to scriptscript_get_compile_feedback - Check compile errors for one script after Unity finishes compilingcreate_script() in scripts/unity_skills.py now waits for Unity to come back once and refreshes compile feedback automatically after script creation.Create a C# script from template.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| scriptName | string | Yes | - | Script class name |
| folder | string | No | "Assets/Scripts" | Save folder |
| template | string | No | "MonoBehaviour" | Template type |
| namespaceName | string | No | null | Optional namespace |
| checkCompile | bool | No | true | Check compilation after create |
| diagnosticLimit | int | No | 20 | Max compile diagnostics |
Templates: MonoBehaviour, ScriptableObject, Editor, EditorWindow
Returns: {success, status, path, jobId, className, namespaceName, designReminder, serverAvailability?}
Poll the returned jobId (or call script_get_compile_feedback) to obtain compile diagnostics — they are not embedded in the synchronous response. serverAvailability carries the transient-unavailable hint when Unity is about to reload the script domain.
Create multiple scripts in one call.
Returns: {success, totalItems, successCount, failCount, results: [{success, path, className}], compilation?}
Before batch creation, decide whether each script should be:
MonoBehaviour bridgeScriptableObject configuration assetunity_skills.call_skill("script_create_batch", items=[
{"scriptName": "PlayerController", "folder": "Assets/Scripts/Player", "template": "MonoBehaviour"},
{"scriptName": "EnemyAI", "folder": "Assets/Scripts/Enemy", "template": "MonoBehaviour"},
{"scriptName": "GameSettings", "folder": "Assets/Scripts/Data", "template": "ScriptableObject"}
])
Read script content.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| scriptPath | string | Yes | Script asset path |
Returns: {path, lines, content}
Delete a script.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| scriptPath | string | Yes | Script to delete |
Returns: {success, status, deleted, jobId, serverAvailability?}
Search for patterns in scripts.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| pattern | string | Yes | - | Search pattern |
| folder | string | No | "Assets" | Search folder |
| isRegex | bool | No | false | Use regex |
| limit | int | No | 50 | Max results |
Returns: {pattern, matchCount, matches: [{file, line, content}]}
Append content to a script.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| scriptPath | string | Yes | - | Script path |
| content | string | Yes | - | Content to append |
| atLine | int | No | end | Line number to insert at |
| checkCompile | bool | No | true | Check compilation after append |
| diagnosticLimit | int | No | 20 | Max compile diagnostics |
Get compile diagnostics related to one script.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| scriptPath | string | Yes | - | Script path |
| limit | int | No | 20 | Max diagnostics |
import unity_skills
# BAD: 3 API calls + 3 Domain Reloads
unity_skills.call_skill("script_create", scriptName="PlayerController", folder="Assets/Scripts/Player")
# Wait for Domain Reload...
unity_skills.call_skill("script_create", scriptName="EnemyAI", folder="Assets/Scripts/Enemy")
# Wait for Domain Reload...
unity_skills.call_skill("script_create", scriptName="GameManager", folder="Assets/Scripts/Core")
# Wait for Domain Reload...
# GOOD: 1 API call + 1 Domain Reload
unity_skills.call_skill("script_create_batch", items=[
{"scriptName": "PlayerController", "folder": "Assets/Scripts/Player"},
{"scriptName": "EnemyAI", "folder": "Assets/Scripts/Enemy"},
{"scriptName": "GameManager", "folder": "Assets/Scripts/Core"}
])
# Wait for Domain Reload once...
After creating or editing scripts, Unity triggers a Domain Reload (recompilation). Use the returned compilation field first. If isCompiling=true, wait for Unity to finish and then call script_get_compile_feedback.
import time
result = unity_skills.call_skill("script_create", scriptName="MyScript")
time.sleep(5) # Wait for Unity to recompile if result["compilation"]["isCompiling"] is true
feedback = unity_skills.call_skill("script_get_compile_feedback", scriptPath=result["path"])
unity_skills.call_skill("component_add", name="Player", componentType="MyScript")
Update, repeated Find, reflection in hot paths, and avoidable allocations10. Use templates for correct base class
11. Wait for compilation after creating scripts
12. After script edits, call script_get_compile_feedback and fix reported errors
13. Use regex search for complex patterns
14. Use batch creation to minimize Domain Reloads
script_replaceFind and replace content in a script file.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| scriptPath | string | Yes | - | Script asset path |
| find | string | Yes | - | Text or pattern to find |
| replace | string | Yes | - | Replacement text |
| isRegex | bool | No | false | Use regex matching |
| checkCompile | bool | No | true | Check compilation after replace |
| diagnosticLimit | int | No | 20 | Max compile diagnostics |
Returns: { success, status, path, jobId, replacements, serverAvailability? }
script_listList C# script files in the project.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| folder | string | No | "Assets" | Folder to search in |
| filter | string | No | null | Filter string for path matching |
| limit | int | No | 100 | Max results |
Returns: { count, scripts: [{ path, name }] }
script_get_infoGet script info (class name, base class, methods).
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| scriptPath | string | Yes | - | Script asset path |
Returns: { path, className, baseClass, namespaceName, isMonoBehaviour, publicMethods, publicFields }
script_renameRename a script file.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| scriptPath | string | Yes | - | Script asset path |
| newName | string | Yes | - | New script name (without extension) |
| checkCompile | bool | No | true | Check compilation after rename |
| diagnosticLimit | int | No | 20 | Max compile diagnostics |
Returns: { success, status, path, jobId, oldPath, newName, serverAvailability? }
script_moveMove a script to a new folder.
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| scriptPath | string | Yes | - | Script asset path |
| newFolder | string | Yes | - | Destination folder. Must already exist. |
| checkCompile | bool | No | true | Check compilation after move |
| diagnosticLimit | int | No | 20 | Max compile diagnostics |
Returns: { success, status, path, jobId, oldPath, newPath, serverAvailability? }
Exact names, parameters, defaults, and returns are defined by GET /skills/schema or unity_skills.get_skill_schema(), not by this file.
Take besty0728/unity-script from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.