用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Besty0728/Unity-Skills --skill unity-material命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Automate the Unity Editor through a local REST API — create and edit scripts, build scenes and prefabs, manage assets/materials/lighting, run tests, and drive hundreds of Editor operations across modules. Use when the user wants to actually operate the Unity Editor from chat — create or modify GameObjects/scripts/scenes/assets, batch-edit, or run Editor automation — in any language. Not needed for conceptual Unity Q&A that touches no Editor state — read the matching advisory doc under skills/ instead. 当用户要从对话里实际操作 Unity 编辑器(创建/修改/批量编辑/运行测试)时使用,任何语言均可触发;纯概念问答无需本协议。
Unified batch and async-job orchestration
Index of all Unity Skills modules with per-module mode labels (SA/FA/Mixed). Use to find which module covers a task before loading its doc.
正在显示 SKILL.md
| name | unity-material |
| description | Edit material and shader properties across Built-in/URP/HDRP |
Before calling any skill in this module: if you are about to call a skill with parameters guessed from its name or description, STOP — read this file (or fetch its schema via
GET /skills/recommend?includeSchema=true) first. If you already have the parameter definitions from recommend/schema, you may proceed straight to dryRun.
BATCH-FIRST: Use
*_batchskills when operating on 2+ objects/materials.
material_create, material_create_batch, material_assign, material_assign_batch, material_duplicate, material_set_color / _emission / _texture / _float / _int / _vector / _keyword / _render_queue / _shader / _texture_offset / _texture_scale / _gi_flags, and the *_batch variants) need user grant; grant triggers a single server-side execution that returns the result.material_get_properties, material_get_keywords) are SkillMode.SemiAuto — they run in all three modes without grant.asset module.DO NOT (common hallucinations):
material_set_metallic / material_set_smoothness do not exist → use material_set_float with propertyName="_Metallic" or "_Glossiness" (Standard) / "_Smoothness" (URP)material_set_color r/g/b/a range is 0–1, not 0–255material_set_property does not exist → use the specific setter: material_set_float, material_set_int, material_set_vector, material_set_colormaterial_get_color does not exist → use material_get_properties (returns all properties including colors)Routing:
material_set_shader (this module)material_set_texture_scale / material_set_texture_offset⚠️ Targeting a GameObject edits the material asset, not that one object. There is no per-object material instance here: every
material_set_*resolves a GameObject torenderer.sharedMaterialand writes the asset on disk — an asset mutation, not a scene edit, whatever the individual skill's declared flags say. A freshly created primitive carries Unity's built-inDefault-Material, somaterial_set_color(name="Cube")recolours every object in the project still using it — the classic "I coloured one cube and the whole scene changed" bug. Target by GameObject name only after confirming that object owns a material nobody else shares (material_get_properties→materialPathnames the asset that would be written).
Safe route for "make this object red" — create, colour the asset by path, then assign:
unity_skills.call_skill("material_create", name="Red", savePath="Assets/Materials")
unity_skills.call_skill("material_set_color", path="Assets/Materials/Red.mat", r=1, g=0, b=0)
unity_skills.call_skill("material_assign", name="Cube", materialPath="Assets/Materials/Red.mat")
Object Targeting: Most single-object skills accept
name(GameObject name) orpath. Behaviour ofpath:
- In
material_set_*/material_get_*(color/emission/texture/float/int/vector/keyword/shader/render_queue/gi_flags/properties),pathmay be either a GameObject hierarchy path or a material asset path likeAssets/Materials/X.mat— the skill auto-detects (paths starting withAssets/or ending with.matare treated as material assets).- In
material_assign,pathis a GameObject hierarchy path only; the material to assign goes in the separatematerialPathparameter.
| Single Object | Batch Version | Use Batch When |
|---|---|---|
material_create | material_create_batch | Creating 2+ materials |
material_assign | material_assign_batch | Assigning to 2+ objects |
material_set_color | material_set_colors_batch | Setting colors on 2+ objects |
material_set_emission | material_set_emission_batch | Setting emission on 2+ objects |
No batch needed:
material_set_texture - Set texturematerial_set_texture_offset / material_set_texture_scale - Texture tilingmaterial_set_float / material_set_int / material_set_vector - Set propertiesmaterial_set_keyword - Enable/disable shader keywordsmaterial_set_render_queue - Set render queuematerial_set_shader - Change shadermaterial_set_gi_flags - Set global illumination flagsmaterial_get_properties / material_get_keywords - Query propertiesmaterial_duplicate - Duplicate materialCreate a new material (auto-detects render pipeline).
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | - | Material name |
shaderName | string | No | auto-detect | Shader (auto-detects URP/HDRP/Standard) |
savePath | string | No | null | Save path (folder or full path) |
Create multiple materials.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
items | json string | Yes | - | JSON array of per-item objects (see example below) |
Returns: {success, totalItems, successCount, failCount, results: [{success, name, path}]}
unity_skills.call_skill("material_create_batch", items=[
{"name": "Red", "savePath": "Assets/Materials"},
{"name": "Blue", "savePath": "Assets/Materials"},
{"name": "Green", "savePath": "Assets/Materials"}
])
Assign material to object's renderer.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject name |
instanceId | int | No* | Instance ID |
path | string | No* | GameObject hierarchy path |
materialPath | string | Yes | Material asset to assign (e.g. Assets/Materials/X.mat) |
Assign materials to multiple objects.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
items | json string | Yes | - | JSON array of per-item objects (see example below) |
Returns: {success, totalItems, successCount, failCount, results: [{success, gameObject, material}]} — each item echoes gameObject (the object name) and material (the assigned asset path); failures come back as {error, target}.
unity_skills.call_skill("material_assign_batch", items=[
{"name": "Cube1", "materialPath": "Assets/Materials/Red.mat"},
{"name": "Cube2", "materialPath": "Assets/Materials/Blue.mat"}
])
Set material color with optional HDR intensity.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | No* | - | GameObject name |
instanceId | int | No* | 0 | GameObject instance ID |
path | string | No* | - | Material asset path |
r, g, b | float | No | 1 | Color (0-1) |
a | float | No | 1 | Alpha |
propertyName | string | No | auto-detect | Color property |
intensity | float | No | 1.0 | HDR intensity (>1 for bloom) |
Returns: {success, target, color, intensity, propertyUsed, hdrEnabled}. Auto-detection tries the pipeline's property first, then _BaseColor, _Color, _TintColor, _EmissionColor, and propertyUsed reports which one it actually wrote — check it before concluding a colour "didn't apply".
Set colors on multiple objects. Each item accepts: identifier (name/instanceId/path) + r, g, b, a, optional per-item propertyName.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
items | json string | Yes | - | JSON array of {name|instanceId|path, r, g, b, a} per-item objects (see example below) |
propertyName | string | No | auto-detect | Default color property applied to all items unless overridden |
Returns: {success, totalItems, successCount, failCount, results: [{target, success}]} — the per-item key is target (GameObject name, or the path when you addressed the asset), not name; failures come back as {error, target}.
unity_skills.call_skill("material_set_colors_batch", items=[
{"name": "Cube1", "r": 1, "g": 0, "b": 0},
{"name": "Cube2", "r": 0, "g": 1, "b": 0},
{"name": "Cube3", "r": 0, "g": 0, "b": 1}
])
Set emission color with auto-enable keyword.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | No* | - | GameObject name |
instanceId | int | No* | 0 | GameObject instance ID |
path | string | No* | - | Material asset path |
r, g, b | float | No | 1 | Emission color (0-1) |
intensity | float | No | 1.0 | HDR intensity (>1 for bloom) |
enableEmission | bool | No | true | Auto-enable _EMISSION keyword |
Set emission on multiple objects.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
items | json string | Yes | - | JSON array of per-item objects (see example below) |
Returns: {success, totalItems, successCount, failCount, results: [{success, name}]}
unity_skills.call_skill("material_set_emission_batch", items=[
{"name": "Neon1", "r": 1, "g": 0, "b": 1, "intensity": 5.0},
{"name": "Neon2", "r": 0, "g": 1, "b": 1, "intensity": 5.0}
])
Set material texture.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | No* | - | GameObject name |
instanceId | int | No* | 0 | GameObject instance ID |
path | string | No* | - | Material asset path |
texturePath | string | Yes | - | Texture asset path |
propertyName | string | No | auto-detect | Texture property |
Set a float property on a material.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject name |
instanceId | int | No* | GameObject instance ID |
path | string | No* | Material asset path |
propertyName | string | Yes | Property name |
value | float | Yes | Value |
Set an integer property on a material.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject name |
instanceId | int | No* | GameObject instance ID |
path | string | No* | Material asset path |
propertyName | string | Yes | Property name |
value | int | Yes | Value |
Enable/disable shader keywords.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | No* | - | GameObject name |
instanceId | int | No* | 0 | GameObject instance ID |
path | string | No* | - | Material asset path |
keyword | string | Yes | - | Keyword name |
enable | bool | No | true | Enable or disable |
Common Keywords: _EMISSION, _NORMALMAP, _METALLICGLOSSMAP, _ALPHATEST_ON, _ALPHABLEND_ON
Get all material properties.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject name |
instanceId | int | No* | GameObject instance ID |
path | string | No* | Material asset path |
Returns: {success, target, materialPath, shader, renderQueue, keywords, giFlags, properties: {...}}
properties is a dictionary of five typed groups, not a flat list: colors, floats, vectors, textures, integers. Each group is an array of {name, description, value} (floats also carry min/max; a texture's value is the texture's name or null). So a property lookup is properties.colors[i].name, never properties[i].
materialPath is the asset path of the material actually inspected, and it is only ever a path you can feed straight back in. It is "" for a built-in material, and also "" for a material embedded in another asset such as an .fbx: that material does have a containing file, but the file's main asset is a GameObject rather than a Material, so handing the .fbx path back would fail with "material not found". An empty materialPath therefore means "this material cannot be addressed by path" — resolve it through its GameObject instead, and do not synthesise a path from the model's. Read it whenever you resolved the material through a GameObject: a non-empty value is the file a subsequent material_set_* on that object would write.
Get all enabled shader keywords on a material.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject name |
instanceId | int | No* | GameObject instance ID |
path | string | No* | Material asset path |
Returns: {success, target, materialPath, shader, enabledKeywords, commonKeywordStatus} — materialPath is the resolved asset path of the material actually inspected (same guarantee as material_get_properties: "" for a built-in material, and "" for one embedded in another asset such as an .fbx, because that container's path is not feedable back in), and commonKeywordStatus is a {keyword, enabled} array covering the 14 usual suspects, so an absent keyword is distinguishable from an unchecked one.
Duplicate a material asset.
| Parameter | Type | Required | Description |
|---|---|---|---|
sourcePath | string | Yes | Source material path |
newName | string | Yes | Name for the duplicated material |
savePath | string | No | Optional folder/path override for the duplicated material |
Change the shader of a material.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject name |
instanceId | int | No* | GameObject instance ID |
path | string | No* | Material asset path |
shaderName | string | Yes | Shader name |
Set a Vector4 property on a material.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject name |
instanceId | int | No* | GameObject instance ID |
path | string | No* | Material asset path |
propertyName | string | Yes | Property name |
x, y, z, w | float | Yes | Vector components |
Set texture offset (tiling position).
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject name |
instanceId | int | No* | GameObject instance ID |
path | string | No* | Material asset path |
propertyName | string | No | Texture property name |
x, y | float | Yes | Offset values |
Set texture scale (tiling).
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject name |
instanceId | int | No* | GameObject instance ID |
path | string | No* | Material asset path |
propertyName | string | No | Texture property name |
x, y | float | Yes | Scale values |
Set material render queue.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject name |
instanceId | int | No* | GameObject instance ID |
path | string | No* | Material asset path |
renderQueue | int | Yes | Render queue value |
Set material global illumination flags.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | No* | - | GameObject name |
instanceId | int | No* | 0 | GameObject instance ID |
path | string | No* | - | GameObject hierarchy path or material asset path |
flags | string | No | RealtimeEmissive | GI flags: None / RealtimeEmissive / BakedEmissive / EmissiveIsBlack / AnyEmissive |
import unity_skills
# BAD: 6 API calls
unity_skills.call_skill("material_create", name="Mat1", savePath="Assets/Materials")
unity_skills.call_skill("material_create", name="Mat2", savePath="Assets/Materials")
unity_skills.call_skill("material_set_color", path="Assets/Materials/Mat1.mat", r=1, g=0, b=0)
unity_skills.call_skill("material_set_color", path="Assets/Materials/Mat2.mat", r=0, g=0, b=1)
unity_skills.call_skill("material_assign", name="Cube1", materialPath="Assets/Materials/Mat1.mat")
unity_skills.call_skill("material_assign", name="Cube2", materialPath="Assets/Materials/Mat2.mat")
# GOOD: 3 API calls
unity_skills.call_skill("material_create_batch", items=[
{"name": "Mat1", "savePath": "Assets/Materials"},
{"name": "Mat2", "savePath": "Assets/Materials"}
])
unity_skills.call_skill("material_set_colors_batch", items=[
{"path": "Assets/Materials/Mat1.mat", "r": 1, "g": 0, "b": 0},
{"path": "Assets/Materials/Mat2.mat", "r": 0, : , : }
])
unity_skills.call_skill(, items=[
{: , : },
{: , : }
])
Skills auto-detect and adapt to your render pipeline:
| Pipeline | Default Shader | Color Property | Texture Property |
|---|---|---|---|
| Built-in | Standard | _Color | _MainTex |
| URP | Universal Render Pipeline/Lit | _BaseColor | _BaseMap |
| HDRP | HDRP/Lit | _BaseColor | _BaseColorMap |
URP Lit exposes both
_BaseColorand a legacy_Color, and only_BaseColoris authoritative.material_get_propertieslists both, but writing_BaseColordoes not update the_Colorentry — a verification pass that reads_Colorwill report the old colour and look like a failed write. Compare against_BaseColor, and trust the setter'spropertyUsedfield over your own guess about which property was involved. Only passpropertyNameexplicitly when auto-detection picked the wrong one.
path="Assets/.../X.mat"): it states exactly which asset changesmaterial_get_propertiesExact names, parameters, defaults, and returns are defined by GET /skills/schema or unity_skills.get_skill_schema(), not by this file.
Full transport-level codes (COMPILING/RATE_LIMIT etc.) → ../../references/protocol-error-codes.md
| Error | Trigger | Fix |
|---|---|---|
TARGET_NOT_FOUND | The material asset, GameObject/renderer, shader, texture, or property could not be found (e.g., Material asset not found, No Renderer component found, Shader not found). | Verify the asset path with asset_find, the object with gameobject_find, or inspect available properties with material_get_properties. |
MISSING_PARAM | A required parameter is missing, such as materialPath, sourcePath, texturePath, propertyName, keyword, or shaderName. | Supply the parameter named in the error and retry; use mode=dryRun for the full schema. |
SEMANTIC_INVALID | An invalid value was supplied, such as an unrecognized GI flag, an invalid asset path, or a property name the shader does not use. | Correct the value using the allowed range/enum/path convention described in the error. |