---
name: unity-skills
description: "Unity Editor automation via REST API. Use when users want to create, modify, or manage GameObjects, components, scenes, materials, prefabs, lights, UI elements, or any Unity Editor operations. Triggers on: Unity, GameObject, prefab, scene, material, component, animator, shader, UI canvas, lighting setup, asset import, play mode, editor automation, Unity编辑器, Unity自动化, Unity场景, Unity物体, Unity组件, Unity材质, Unity预制体, Unity灯光, Unity动画, Unity脚本."
---

# Unity Skills API

> **RULE**: 2+ objects → use `*_batch` skill (1 call vs N calls)

## Version Routing (Multi-Instance)

When user mentions a specific Unity version, set target **before** any operations:

```python
import unity_skills
unity_skills.set_unity_version("6")      # Unity 6 (matches 6000.x.x)
unity_skills.set_unity_version("2023")   # Unity 2023.x
unity_skills.set_unity_version("2022")   # Unity 2022.x
unity_skills.set_unity_version("2021")   # Unity 2021.x
```

| User says | Call |
|-----------|------|
| "Unity 6" / "Unity6" / "Unity 6.2" | `set_unity_version("6")` |
| "2023" / "Unity 2023" | `set_unity_version("2023")` |
| "2022" / "Unity 2022" | `set_unity_version("2022")` |
| "2021" / "Unity 2021" | `set_unity_version("2021")` |

`list_instances()` → returns all running instances with `unityVersion`, `port`, `name`

## Batch Skills (Use First!)

| Skill | items format |
|-------|--------------|
| `gameobject_create_batch` | `[{name, primitiveType?, x?, y?, z?, parentName?}]` |
| `gameobject_delete_batch` | `[{name?, instanceId?}]` or `["name1","name2"]` |
| `gameobject_set_transform_batch` | `[{name, posX?, posY?, posZ?, rotX?, rotY?, rotZ?, scaleX?, scaleY?, scaleZ?}]` |
| `gameobject_set_active_batch` | `[{name, active}]` |
| `gameobject_set_parent_batch` | `[{childName, parentName}]` |
| `gameobject_duplicate_batch` | `[{name?, instanceId?}]` |
| `gameobject_rename_batch` | `[{instanceId, newName}]` |
| `gameobject_set_layer_batch` | `[{name, layer}]` |
| `gameobject_set_tag_batch` | `[{name, tag}]` |
| `component_add_batch` | `[{name, componentType}]` |
| `component_remove_batch` | `[{name, componentType}]` |
| `component_set_property_batch` | `[{name, componentType, propertyName, value}]` |
| `material_create_batch` | `[{name, shaderName?, savePath?}]` |
| `material_assign_batch` | `[{name, materialPath}]` |
| `material_set_colors_batch` | `[{name?, path?, r, g, b, a?, intensity?}]` |
| `material_set_emission_batch` | `[{name?, path?, r, g, b, intensity?}]` |
| `prefab_instantiate_batch` | `[{prefabPath, x?, y?, z?, rotX?, rotY?, rotZ?, name?, parentName?}]` |
| `asset_import_batch` | `[{sourcePath, destinationPath}]` |
| `asset_delete_batch` | `[{path}]` |
| `asset_move_batch` | `[{sourcePath, destinationPath}]` |
| `ui_create_batch` | `[{type, name, parent?, text?, width?, height?, x?, y?}]` type: Button/Text/Image/Panel/Slider/Toggle/InputField |
| `script_create_batch` | `[{scriptName, folder?, template?, namespace?}]` |
| `light_set_properties_batch` | `[{name, intensity?, r?, g?, b?, range?, shadows?}]` |
| `light_set_enabled_batch` | `[{name, enabled}]` |
| `texture_set_settings_batch` | `[{assetPath, textureType?, maxSize?, filterMode?, compression?, mipmapEnabled?, spritePixelsPerUnit?}]` |
| `audio_set_settings_batch` | `[{assetPath, loadType?, compressionFormat?, quality?, forceToMono?}]` |
| `model_set_settings_batch` | `[{assetPath, animationType?, meshCompression?, importAnimation?}]` |

## Single Skills

### gameobject
| Skill | Parameters |
|-------|------------|
| `gameobject_create` | name?, primitiveType?, x?, y?, z?, parentName? |
| `gameobject_delete` | name?, instanceId?, path? |
| `gameobject_find` | name?, tag?, layer?, component?, useRegex?, limit? → returns list |
| `gameobject_get_info` | name?, instanceId?, path? |
| `gameobject_set_transform` | name, posX?, posY?, posZ?, rotX?, rotY?, rotZ?, scaleX?, scaleY?, scaleZ? |
| `gameobject_set_parent` | name, parentName |
| `gameobject_set_active` | name, active |
| `gameobject_duplicate` | name?, instanceId? → returns copyName, copyInstanceId |
| `gameobject_rename` | name?, instanceId?, newName |

primitiveType: Cube, Sphere, Capsule, Cylinder, Plane, Quad, Empty(null)

### component
| Skill | Parameters |
|-------|------------|
| `component_add` | name, componentType |
| `component_remove` | name, componentType |
| `component_list` | name → returns components[] |
| `component_set_property` | name, componentType, propertyName, value |
| `component_get_properties` | name, componentType |

componentType: Rigidbody, BoxCollider, SphereCollider, CapsuleCollider, MeshCollider, CharacterController, AudioSource, Light, Camera, Animator, etc.

### material
| Skill | Parameters |
|-------|------------|
| `material_create` | name, shaderName?, savePath? |
| `material_assign` | name?, instanceId?, path?, materialPath |
| `material_set_color` | name?, path?, r, g, b, a?, propertyName?, intensity? |
| `material_set_emission` | name?, path?, r, g, b, intensity?, enableEmission? |
| `material_set_texture` | name?, path?, texturePath, propertyName? |
| `material_set_float` | name?, path?, propertyName, value |
| `material_set_int` | name?, path?, propertyName, value |
| `material_set_vector` | name?, path?, propertyName, x, y, z?, w? |
| `material_set_keyword` | name?, path?, keyword, enable? |
| `material_set_render_queue` | name?, path?, renderQueue |
| `material_set_shader` | name?, path?, shaderName |
| `material_set_texture_offset` | name?, path?, propertyName?, x, y |
| `material_set_texture_scale` | name?, path?, propertyName?, x, y |
| `material_get_properties` | name?, path? |
| `material_get_keywords` | name?, path? |
| `material_duplicate` | sourcePath, newName, savePath? |

### scene
| Skill | Parameters |
|-------|------------|
| `scene_create` | scenePath |
| `scene_load` | scenePath, additive? |
| `scene_save` | scenePath? |
| `scene_get_info` | (none) → name, path, isDirty, rootObjects |
| `scene_get_hierarchy` | maxDepth? → hierarchy tree |
| `scene_screenshot` | filename?, width?, height? |

### light
| Skill | Parameters |
|-------|------------|
| `light_create` | name?, lightType?, x?, y?, z?, r?, g?, b?, intensity?, range?, spotAngle?, shadows? |
| `light_set_properties` | name, r?, g?, b?, intensity?, range?, shadows? |
| `light_get_info` | name |
| `light_find_all` | lightType?, limit? → returns list |
| `light_set_enabled` | name, enabled |

lightType: Directional, Point, Spot, Area | shadows: none, hard, soft

### prefab
| Skill | Parameters |
|-------|------------|
| `prefab_create` | gameObjectName?, instanceId?, savePath |
| `prefab_instantiate` | prefabPath, x?, y?, z?, name?, parentName? |
| `prefab_apply` | gameObjectName?, instanceId? |
| `prefab_unpack` | gameObjectName?, instanceId?, completely? |

### asset
| Skill | Parameters |
|-------|------------|
| `asset_import` | sourcePath, destinationPath |
| `asset_delete` | assetPath |
| `asset_move` | sourcePath, destinationPath |
| `asset_duplicate` | assetPath |
| `asset_find` | searchFilter, searchInFolders?, limit? → returns paths |
| `asset_create_folder` | folderPath |
| `asset_refresh` | (none) |
| `asset_get_info` | assetPath |

searchFilter: t:Texture2D, t:Material, t:Prefab, t:AudioClip, t:Script, name, l:Label

### ui
| Skill | Parameters |
|-------|------------|
| `ui_create_canvas` | name?, renderMode? |
| `ui_create_panel` | name?, parent?, r?, g?, b?, a?, width?, height? |
| `ui_create_button` | name?, parent?, text?, width?, height?, x?, y? |
| `ui_create_text` | name?, parent?, text?, fontSize?, r?, g?, b?, a?, width?, height? |
| `ui_create_image` | name?, parent?, spritePath?, r?, g?, b?, a?, width?, height? |
| `ui_create_inputfield` | name?, parent?, placeholder?, width?, height? |
| `ui_create_slider` | name?, parent?, minValue?, maxValue?, value?, width?, height? |
| `ui_create_toggle` | name?, parent?, label?, isOn? |
| `ui_set_text` | name, text |
| `ui_find_all` | uiType?, limit? |

renderMode: ScreenSpaceOverlay, ScreenSpaceCamera, WorldSpace | uiType: Button, Text, Image, Panel, Slider, Toggle, InputField

### script
| Skill | Parameters |
|-------|------------|
| `script_create` | scriptName, folder?, template?, namespace? |
| `script_read` | scriptPath → content |
| `script_delete` | scriptPath |
| `script_find_in_file` | pattern, folder?, isRegex?, limit? → matches |
| `script_append` | scriptPath, content, atLine? |

template: MonoBehaviour, ScriptableObject, Editor, EditorWindow

### editor
| Skill | Parameters |
|-------|------------|
| `editor_play` | (none) |
| `editor_stop` | (none) |
| `editor_pause` | (none) |
| `editor_select` | gameObjectName?, instanceId? |
| `editor_get_selection` | (none) → selected objects with instanceId |
| `editor_get_context` | includeComponents?, includeChildren? → selection, assets, scene info |
| `editor_undo` | (none) |
| `editor_redo` | (none) |
| `editor_get_state` | (none) → isPlaying, isPaused, isCompiling |
| `editor_execute_menu` | menuPath |
| `editor_get_tags` | (none) |
| `editor_get_layers` | (none) |

menuPath: "File/Save", "Edit/Play", "GameObject/Create Empty", "Assets/Refresh"

### animator
| Skill | Parameters |
|-------|------------|
| `animator_create_controller` | name, folder? |
| `animator_add_parameter` | controllerPath, paramName, paramType, defaultValue? |
| `animator_get_parameters` | controllerPath |
| `animator_set_parameter` | name, paramName, paramType, floatValue?/intValue?/boolValue? |
| `animator_play` | name, stateName, layer?, normalizedTime? |
| `animator_get_info` | name |
| `animator_assign_controller` | name, controllerPath |
| `animator_list_states` | controllerPath, layer? |

paramType: float, int, bool, trigger

### shader
| Skill | Parameters |
|-------|------------|
| `shader_create` | shaderName, savePath, template? |
| `shader_read` | shaderPath |
| `shader_list` | filter?, limit? |

template: Unlit, Standard, Transparent

### workflow (Persistent History)
| Skill | Parameters |
|-------|------------|
| `workflow_task_start` | tag, description? |
| `workflow_task_end` | (none) |
| `workflow_snapshot_object` | name?, instanceId? |
| `workflow_list` | (none) |
| `workflow_revert_task` | taskId |
| `workflow_delete_task` | taskId |

### console
| Skill | Parameters |
|-------|------------|
| `console_start_capture` | (none) |
| `console_stop_capture` | (none) |
| `console_get_logs` | filter?, limit? |
| `console_clear` | (none) |
| `console_log` | message, type? |

filter/type: Log, Warning, Error

### validation
| Skill | Parameters |
|-------|------------|
| `validate_scene` | checkMissingScripts?, checkMissingPrefabs?, checkDuplicateNames? |
| `validate_find_missing_scripts` | searchInPrefabs? |
| `validate_fix_missing_scripts` | dryRun? (default true) |
| `validate_cleanup_empty_folders` | rootPath?, dryRun? (default true) |
| `validate_find_unused_assets` | assetType?, limit? |
| `validate_texture_sizes` | maxRecommendedSize?, limit? |
| `validate_project_structure` | rootPath?, maxDepth? |

### importer
| Skill | Parameters |
|-------|------------|
| `texture_get_settings` | assetPath |
| `texture_set_settings` | assetPath, textureType?, maxSize?, filterMode?, compression?, mipmapEnabled?, sRGB?, readable?, spritePixelsPerUnit?, wrapMode? |
| `audio_get_settings` | assetPath |
| `audio_set_settings` | assetPath, forceToMono?, loadInBackground?, preloadAudioData?, loadType?, compressionFormat?, quality? |
| `model_get_settings` | assetPath |
| `model_set_settings` | assetPath, globalScale?, meshCompression?, isReadable?, generateSecondaryUV?, importBlendShapes?, importCameras?, importLights?, animationType?, importAnimation?, materialImportMode? |

textureType: Default, NormalMap, Sprite, EditorGUI, Cursor, Cookie, Lightmap, SingleChannel
filterMode: Point, Bilinear, Trilinear | compression: None, LowQuality, Normal, HighQuality
loadType: DecompressOnLoad, CompressedInMemory, Streaming | compressionFormat: PCM, Vorbis, ADPCM
animationType: None, Legacy, Generic, Humanoid | meshCompression: Off, Low, Medium, High

### physics
| Skill | Parameters |
|-------|------------|
| `physics_raycast` | originX, originY, originZ, dirX, dirY, dirZ, maxDistance?, layerMask? |
| `physics_check_overlap` | x, y, z, radius, layerMask? |
| `physics_get_gravity` | (none) |
| `physics_set_gravity` | x, y, z |

### camera
| Skill | Parameters |
|-------|------------|
| `camera_align_view_to_object` | objectName |
| `camera_get_info` | (none) |
| `camera_set_transform` | posX, posY, posZ, rotX, rotY, rotZ, size?, instant? |
| `camera_look_at` | x, y, z |

### navmesh
| Skill | Parameters |
|-------|------------|
| `navmesh_bake` | (none) |
| `navmesh_calculate_path` | startX, startY, startZ, endX, endY, endZ, areaMask? |

### timeline
| Skill | Parameters |
|-------|------------|
| `timeline_create` | name, folder? |
| `timeline_add_audio_track` | directorObjectName, trackName? |
| `timeline_add_animation_track` | directorObjectName, trackName?, bindingObjectName? |

### cinemachine
| Skill | Parameters |
|-------|------------|
| `cinemachine_create_vcam` | name |
| `cinemachine_set_vcam_property` | vcamName, componentType, propertyName, value |
| `cinemachine_set_targets` | vcamName, followName?, lookAtName? |

### event
| Skill | Parameters |
|-------|------------|
| `event_get_listeners` | objectName, componentName, eventName |
| `event_add_listener` | objectName, componentName, eventName, targetObjectName, ... |
| `event_invoke` | objectName, componentName, eventName |

### project
| Skill | Parameters |
|-------|------------|
| `project_get_info` | (none) |
| `project_list_shaders` | filter?, limit? |
| `project_get_quality_settings` | (none) |

### optimization
| Skill | Parameters |
|-------|------------|
| `optimize_textures` | maxTextureSize?, enableCrunch?, compressionQuality? |
| `optimize_mesh_compression` | compressionLevel, filter? |

### profiler
| Skill | Parameters |
|-------|------------|
| `profiler_get_stats` | (none) |

### package
| Skill | Parameters |
|-------|------------|
| `package_list` | (none) → returns installed packages |
| `package_check` | packageId → returns installed, version |
| `package_install` | packageId, version? |
| `package_remove` | packageId |
| `package_refresh` | (none) |
| `package_install_cinemachine` | version? (2 or 3, default 3) |
| `package_get_cinemachine_status` | (none) → returns cinemachine/splines status |

## Notes
- Response: `{success: true/false, ...data}` or `{success: false, error: "message"}`
- All operations auto-revert on failure
- After `script_create`, wait 3-5s for Unity recompile
- Use `instanceId` (from `editor_get_selection`/`editor_get_context`) for guaranteed uniqueness
- `name?` means use name OR instanceId OR path to identify object
