关于 unity-material
为 Unity 项目管理材质的技能模块,面向需要调整外观、着色器和材质属性的工作流。支持批量操作,并提示修改共享材质资产可能影响多个物体。
主要功能
- 01创建、复制和分配材质
- 02设置颜色、发光和纹理
- 03调整着色器及材质属性
- 04批量处理多个材质或物体
- 05查询材质属性与关键字
适用场景
- 01创建并配置项目材质
- 02为多个物体分配或设置材质
- 03调整纹理缩放、渲染队列或 GI 标记
MCP 相关
该模块通过技能提供 Unity 材质操作能力。变更技能默认需要用户授权,也可在 Auto / Bypass 模式下直接执行;查询技能可在各模式下运行。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ besty0728/ unity-skills --skill unity-material安装后在 Claude Code 中输入/unity-material确认已加载。
详细介绍
**在调用此模块中的任何技能之前:**如果你打算根据技能名称或描述猜测参数后调用技能,请先停下——阅读此文件(或通过
GET /skills/recommend?includeSchema=true获取其 schema)。如果你已从 recommend/schema 获得参数定义,则可直接进行 dryRun。
触发条件
- 更改界面的外观
- 调整材质参数
- 更换 Shader
- 调整物体外观、修改材质参数、切换 Shader
Unity 材质技能
优先批量处理:操作 2 个或更多物体/材质时,使用
*_batch技能。
操作模式
- 审批(默认):所有会更改内容的技能(
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及其*_batch变体)都需要用户授权;授权会触发一次服务器端执行并返回结果。 - 自动 / 绕过:这些技能会直接执行。
- 查询技能(
material_get_properties、material_get_keywords)为SkillMode.SemiAuto——无需授权,即可在所有三种模式下运行。 - 此模块不包含 Delete / PlayMode / Reload / 高风险技能(没有 NeverInSemi);要删除材质资源,请调用
asset模块。
防护规则
请勿(常见幻觉):
material_set_metallic/material_set_smoothness不存在 → 使用material_set_float,并将propertyName设为"_Metallic"或"_Glossiness"(Standard)/"_Smoothness"(URP)material_set_color的 r/g/b/a 范围为 0–1,而非 0–255material_set_property不存在 → 使用对应的 setter:material_set_float、material_set_int、material_set_vector、material_set_colormaterial_get_color不存在 → 使用material_get_properties(返回所有属性,包括颜色)
路由:
- 更改 Shader → 使用
material_set_shader(此模块) - 调整纹理平铺 → 使用
material_set_texture_scale/material_set_texture_offset - 不同渲染管线的属性名称有所不同:请查看本文档中的渲染管线兼容性表
⚠️ 以 GameObject 为目标进行操作时,修改的是材质资源,而非该物体本身。 此处没有针对单个物体的材质实例:每个
material_set_*都会将 GameObject 解析为renderer.sharedMaterial,并写入磁盘上的资源——这是资源变更,不是场景编辑,无论相应技能声明了何种标志。新创建的基本体会使用 Unity 内置的Default-Material,因此material_set_color(name="Cube")会重新着色项目中所有仍在使用该材质的物体——这就是经典的“我给一个立方体上了色,整个场景都变了”问题。只有在确认该物体拥有独占材质(material_get_properties→materialPath指向将被写入的资源)后,才按 GameObject 名称指定目标。
“将此物体设为红色”的安全操作流程——创建资源,按路径为资源着色,然后分配:
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")
物体定位:大多数单物体技能都接受
name(GameObject 名称)或path。path的行为如下:
- 在
material_set_*/material_get_*(color/emission/texture/float/int/vector/keyword/shader/render_queue/gi_flags/properties)中,path可以是 GameObject 层级路径,也可以是类似Assets/Materials/X.mat的材质资源路径——技能会自动识别(以Assets/开头或以.mat结尾的路径会被视为材质资源)。- 在
material_assign中,path仅用于 GameObject 层级路径;要分配的材质应填入单独的materialPath参数。
技能概览
| 单个对象 | 批量版本 | 适用批量操作的情况 |
|---|---|---|
material_create | material_create_batch | 创建 2 个或更多材质 |
material_assign | material_assign_batch | 为 2 个或更多对象分配材质 |
material_set_color | material_set_colors_batch | 为 2 个或更多对象设置颜色 |
material_set_emission | material_set_emission_batch | 为 2 个或更多对象设置发射属性 |
无需批量操作:
material_set_texture- 设置纹理material_set_texture_offset/material_set_texture_scale- 设置纹理平铺material_set_float/material_set_int/material_set_vector- 设置属性material_set_keyword- 启用或禁用着色器关键字material_set_render_queue- 设置渲染队列material_set_shader- 更改着色器material_set_gi_flags- 设置全局光照标志material_get_properties/material_get_keywords- 查询属性material_duplicate- 复制材质
技能
material_create
创建新材质(自动检测渲染管线)。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
name | string | 是 | - | 材质名称 |
shaderName | string | 否 | 自动检测 | 着色器(自动检测 URP/HDRP/Standard);无法解析的名称将回退到管线默认值,响应中会添加 shaderRequested + warnings |
savePath | string | 否 | null | Assets/...,或嵌入式/本地包中的文件夹(Packages/<id>/...);只读包会被拒绝 |
material_create_batch
创建多个材质。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
items | json string | 是 | - | 每项对象组成的 JSON 数组(见下方示例) |
返回值:{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"}
])
material_assign
将材质分配给对象的渲染器。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 否* | GameObject 名称 |
instanceId | int | 否* | 实例 ID |
path | string | 否* | GameObject 层级路径 |
materialPath | string | 是 | 要分配的材质资源(例如 Assets/Materials/X.mat) |
material_assign_batch
为多个对象分配材质。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
items | json string | 是 | - | 每项对象组成的 JSON 数组(见下方示例) |
返回值:{success, totalItems, successCount, failCount, results: [{success, gameObject, material}]} — 每项会返回 gameObject(对象名称)和 material(已分配的资源路径);失败项会返回 {error, target}。
unity_skills.call_skill("material_assign_batch", items=[
{"name": "Cube1", "materialPath": "Assets/Materials/Red.mat"},
{"name": "Cube2", "materialPath": "Assets/Materials/Blue.mat"}
])
material_set_color
设置材质颜色,并可选设置 HDR 强度。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
name | string | 否* | - | GameObject 名称 |
instanceId | int | 否* | 0 | GameObject 实例 ID |
path | string | 否* | - | 材质资源路径 |
r、g、b | float | 否 | 1 | 颜色(0-1) |
a | float | 否 | 1 | Alpha |
propertyName | string | 否 | 自动检测 | 颜色属性 |
intensity | float | 否 | 1.0 | HDR 强度(>1 可产生泛光) |
返回值:{success, target, color, intensity, propertyUsed, hdrEnabled, materialPath}。自动检测会先尝试渲染管线的属性,再依次尝试 _BaseColor、_Color、_TintColor、_EmissionColor,并且 propertyUsed 会报告实际写入的属性——如果颜色“未生效”,请先检查该值。若指定的 propertyName 不存在于着色器中(或指定的是 _Metallic 这类非颜色属性),则会通过 validValues 拒绝;如果指定的属性不存在,但属于 _BaseColor/_Color/_MainColor/_TintColor,则会回退到该属性族中存在的属性(通过 propertyRequested 和 warnings 报告)。显式指定属性时,绝不会回退到 _EmissionColor。
material_set_colors_batch
为多个对象设置颜色。每个条目接受:标识符(name/instanceId/path)+ r、g、b、a,以及可选的条目级 propertyName(遵循与 material_set_color 相同的解析规则;优先级高于批次级 propertyName)。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
items | json string | 是 | - | 每个条目对应一个 {name|instanceId|path, r, g, b, a, propertyName?} 对象的 JSON 数组(示例见下文) |
propertyName | string | 否 | 自动检测 | 应用于所有条目的默认颜色属性,除非被覆盖 |
返回值:{success, totalItems, successCount, failCount, results: [{target, success, propertyUsed, color}]}——每个条目使用的键是 target(GameObject 名称,或通过路径指定资源时使用的路径),而非 name;若某个条目被拒绝,则整个批次失败并回滚其他条目(rolledBack:true、results[i].reverted:true)。
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}
])
material_set_emission
设置发射颜色并自动启用关键字。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
name | string | 否* | - | GameObject 名称 |
instanceId | int | 否* | 0 | GameObject 实例 ID |
path | string | 否* | - | 材质资源路径 |
r、g、b | float | 否 | 1 | 发射颜色(0-1) |
intensity | float | 否 | 1.0 | HDR 强度(>1 可产生泛光) |
enableEmission | bool | 否 | true | 自动启用 _EMISSION 关键字 |
material_set_emission_batch
为多个对象设置发射属性。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
items | json string | 是 | - | 每个条目对应一个对象的 JSON 数组(示例见下文) |
返回值:{success, totalItems, successCount, failCount, results: [{success, target, emissionColor, intensity, hdrColor, emissionEnabled}]}——若某个条目被拒绝,则整个批次失败并回滚其他条目(rolledBack:true)。
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}
])
material_set_texture
设置材质纹理。
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
name | string | 否* | - | GameObject 名称 |
instanceId | int | 否* | 0 | GameObject 实例 ID |
path | string | 否* | - | 材质资源路径 |
texturePath | string | 是 | - | 纹理资源路径 |
propertyName | string | 否 | 自动检测 | 纹理属性 |
material_set_float
设置材质的 float 属性。
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject 名称 |
instanceId | int | No* | GameObject 实例 ID |
path | string | No* | 材质资源路径 |
propertyName | string | Yes | 属性名称 |
value | float | No | 值(默认值为 0) |
material_set_int
设置材质的整数属性。
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject 名称 |
instanceId | int | No* | GameObject 实例 ID |
path | string | No* | 材质资源路径 |
propertyName | string | Yes | 属性名称 |
value | int | No | 值(默认值为 0) |
material_set_keyword
启用或禁用着色器关键字。
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | No* | - | GameObject 名称 |
instanceId | int | No* | 0 | GameObject 实例 ID |
path | string | No* | - | 材质资源路径 |
keyword | string | Yes | - | 关键字名称 |
enable | bool | No | true | 启用或禁用 |
常用关键字:_EMISSION、_NORMALMAP、_METALLICGLOSSMAP、_ALPHATEST_ON、_ALPHABLEND_ON
material_get_properties
获取材质的所有属性。
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject 名称 |
instanceId | int | No* | GameObject 实例 ID |
path | string | No* | 材质资源路径 |
返回:{success, target, materialPath, shader, renderQueue, keywords, giFlags, properties: {...}}
properties 是由五组带类型的属性构成的字典,而非扁平列表:colors、floats、vectors、textures、integers。每组都是由 {name, description, value} 组成的数组(floats 还包含 min/max;纹理的 value 是纹理名称或 null)。因此,查找属性时应使用 properties.colors[i].name,而不是 properties[i]。
materialPath 是实际检查的材质的资源路径,并且始终是可直接传回的路径。内置材质的值为 "";嵌入其他资源(例如 .fbx)中的材质也为 "":这类材质确实有所属文件,但该文件的主资源是 GameObject 而非 Material,因此传回 .fbx 路径会报错 "material not found"。因此,空的 materialPath 表示“无法通过路径定位此材质”——应通过其 GameObject 来解析,不要根据模型路径自行拼造路径。通过 GameObject 解析材质时,请读取此值:非空值就是后续对该对象执行 material_set_* 时会写入的文件。
material_get_keywords
获取材质上所有已启用的着色器关键字。
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No* | GameObject 名称 |
instanceId | int | No* | GameObject 实例 ID |
path | string | No* | 材质资源路径 |
返回:{success, target, materialPath, shader, enabledKeywords, commonKeywordStatus} — materialPath 是实际检查的材质解析后的资源路径(与 material_get_properties 的保证相同:内置材质为 "";嵌入其他资源(例如 .fbx)中的材质也为 "",因为该容器的路径无法传回使用);commonKeywordStatus 是一个 {keyword, enabled} 数组,涵盖 14 个常见关键字,因此可以区分关键字不存在和未勾选。
material_duplicate
复制材质资源。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
sourcePath | string | 是 | 源材质路径 |
newName | string | 是 | 副本材质的名称 |
savePath | string | 否 | 副本材质的可选文件夹/路径覆盖值;可使用 Assets/... 或嵌入式/本地程序包文件夹,不接受只读程序包。省略时:保存在源材质旁边 |
material_set_shader
更改材质的着色器。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
name | string | 否* | GameObject 名称 |
instanceId | int | 否* | GameObject 实例 ID |
path | string | 否* | 材质资源路径 |
shaderName | string | 是 | 着色器名称 |
material_set_vector
设置材质上的 Vector4 属性。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
name | string | 否* | GameObject 名称 |
instanceId | int | 否* | GameObject 实例 ID |
path | string | 否* | 材质资源路径 |
propertyName | string | 是 | 属性名称 |
x, y, z, w | float | 是 | 向量分量 |
material_set_texture_offset
设置纹理偏移(平铺位置)。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
name | string | 否* | GameObject 名称 |
instanceId | int | 否* | GameObject 实例 ID |
path | string | 否* | 材质资源路径 |
propertyName | string | 否 | 纹理属性名称 |
x, y | float | 是 | 偏移值 |
material_set_texture_scale
设置纹理缩放(平铺)。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
name | string | 否* | GameObject 名称 |
instanceId | int | 否* | GameObject 实例 ID |
path | string | 否* | 材质资源路径 |
propertyName | string | 否 | 纹理属性名称 |
x, y | float | 是 | 缩放值 |
material_set_render_queue
设置材质渲染队列。
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
name | string | 否* | GameObject 名称 |
instanceId | int | 否* | GameObject 实例 ID |
path | string | 否* | 材质资源路径 |
renderQueue | int | 否 | 渲染队列值(默认值 -1 = 着色器默认值) |
material_set_gi_flags
设置材质的全局光照标志。
| 参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
name | string | 否* | - | GameObject 名称 |
instanceId | int | 否* | 0 | GameObject 实例 ID |
path | string | 否* | - | GameObject 层级路径或材质资源路径 |
flags | string | 否 | RealtimeEmissive | GI 标志: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, "g": 0, "b": 1}
])
unity_skills.call_skill("material_assign_batch", items=[
{"name": "Cube1", "materialPath": "Assets/Materials/Mat1.mat"},
{"name": "Cube2", "materialPath": "Assets/Materials/Mat2.mat"}
])
渲染管线兼容性
技能会自动检测并适配你的渲染管线:
| 管线 | 默认着色器 | 颜色属性 | 纹理属性 |
|---|---|---|---|
| 内置 | Standard | _Color | _MainTex |
| URP | Universal Render Pipeline/Lit | _BaseColor | _BaseMap |
| HDRP | HDRP/Lit | _BaseColor | _BaseColorMap |
URP Lit 同时公开
_BaseColor和旧版_Color,其中只有_BaseColor是权威值。material_get_properties会列出两者,但写入_BaseColor不会更新_Color条目——读取_Color的验证过程会报告旧颜色,看起来就像写入失败。请与_BaseColor比较,并以 setter 的propertyUsed字段为准,不要自行猜测使用了哪个属性。只有在自动检测选错属性时,才显式传入propertyName。
最佳实践
- 将素材保存为资源,以便重复使用
- 按资源路径编写(
path="Assets/.../X.mat"):这样可以明确指定要更改的资源 - 按 GameObject 名称定位时,会写入该渲染器的共享材质资源——请参阅本文件顶部的警告;这不是针对单个对象的覆盖设置
- 在 Unity 检视面板中检查着色器属性名称,或通过
material_get_properties读取 - URP/HDRP 的属性名称与 Standard 不同
精确签名
精确的名称、参数、默认值和返回值由 GET /skills/schema 或 unity_skills.get_skill_schema() 定义,而非本文件。
常见错误
完整的传输层错误代码(COMPILING/RATE_LIMIT 等)→ ../../references/protocol-error-codes.md
| 错误 | 触发条件 | 修复方法 |
|---|---|---|
TARGET_NOT_FOUND | 找不到材质资源、GameObject/渲染器、着色器、纹理或属性(例如,Material asset not found、No Renderer component found、Shader not found)。 | 使用 asset_find 验证资源路径,使用 gameobject_find 检查对象,或通过 material_get_properties 查看可用属性。 |
MISSING_PARAM | 缺少必需参数,例如 materialPath、sourcePath、texturePath、propertyName、keyword 或 shaderName。 | 提供错误中指定的参数并重试;使用 mode=dryRun 获取完整架构。 |
SEMANTIC_INVALID | 提供了无效值,例如无法识别的 GI 标记、无效的资源路径、着色器未使用的属性名称,或着色器未声明为颜色的 propertyName。 | 根据错误中说明的允许范围、枚举值或路径约定更正该值。 |