将 float2/vector2 属性 从着色器公开到 Unity 材质检查器
Expose float2/vector2 property from shader to Unity material inspector
在 Unity shaderlab 着色器中,您可以将着色器属性公开给编辑器中的材质检查器。这可以通过将要公开的属性放在 Properties
部分中来完成,就像这样
Properties
{
_SomeFloat("A Float", float) = 5
}
Unity 在 documentation here.
中定义了一个属性列表
然而,这不包括任何形式的 float2 或 vector2,仅包含 Float
或 Vector
,其中包含 xyzw
.
我尝试将 属性 类型设置为 float2
和 Vector2
_SomeFloat("A Float", float2) = (5,5)
_SomeFloat2("A Float2", Vector2) = (5,5)
这两个return错误Parse error: syntax error, unexpected TVAL_ID at line 7
或尝试通过仅设置一半成员
来将 Vector
减半
_SomeFloat("A Float", Vector) = (5,5)
哪个return错误Parse error: syntax error, unexpected ')', expecting ','
我可以只使用 Vector 类型,并且只使用它的 xy
,但这会导致不清楚 UI,因为检查器中现在有两个未使用的元素,并且找不到 属性 属性或抽屉(例如 HideInInspector
)允许您对检查器隐藏 zw
值。
那么有没有办法使用 属性 类型公开 float2?或者,您可以在编辑器中将两个浮动属性彼此相邻放置,例如 Tiling/Offset 抽屉是标准 2D
属性 类型(可能类似于 [EditorGUILayout.BeginHorizontal][2]
)?
通过快速搜索,我发现有 MaterialPropertyDrawer
可以扩展以在着色器检查器中添加自定义标签(参考:https://docs.unity3d.com/ScriptReference/MaterialPropertyDrawer.html)。
因此,您可以在着色器中使用 Vector
属性,创建自定义属性,比方说,[ShowAsVector2]
并为其制作 MaterialPropertyDrawer
,这只会显示两个输入字段,并将它们的值分配给向量的 x
和 y
值。这将导致着色器 属性 写为:
[ShowAsVector2] _Position2D("Position", Vector) = (0, 0, 0, 0)
这是@tsvedas 回答的扩展。
using UnityEngine;
using UnityEditor;
/// <summary>
/// Draws a vector2 field for vector properties.
/// Usage: [ShowAsVector2] _Vector2("Vector 2", Vector) = (0,0,0,0)
/// </summary>
public class ShowAsVector2Drawer : MaterialPropertyDrawer
{
public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor)
{
if( prop.type == MaterialProperty.PropType.Vector )
{
EditorGUIUtility.labelWidth = 0f;
EditorGUIUtility.fieldWidth = 0f;
if (!EditorGUIUtility.wideMode)
{
EditorGUIUtility.wideMode = true;
EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - 212;
}
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
Vector4 vec = EditorGUI.Vector2Field(position, label, prop.vectorValue);
if (EditorGUI.EndChangeCheck()) {
prop.vectorValue = vec;
}
}
else
editor.DefaultShaderProperty( prop, label.text );
}
}
只需将此脚本放在 Editor 文件夹中,您应该只能看到 x 和 y 坐标。
在 Unity shaderlab 着色器中,您可以将着色器属性公开给编辑器中的材质检查器。这可以通过将要公开的属性放在 Properties
部分中来完成,就像这样
Properties
{
_SomeFloat("A Float", float) = 5
}
Unity 在 documentation here.
中定义了一个属性列表然而,这不包括任何形式的 float2 或 vector2,仅包含 Float
或 Vector
,其中包含 xyzw
.
我尝试将 属性 类型设置为 float2
和 Vector2
_SomeFloat("A Float", float2) = (5,5)
_SomeFloat2("A Float2", Vector2) = (5,5)
这两个return错误Parse error: syntax error, unexpected TVAL_ID at line 7
或尝试通过仅设置一半成员
来将Vector
减半
_SomeFloat("A Float", Vector) = (5,5)
哪个return错误Parse error: syntax error, unexpected ')', expecting ','
我可以只使用 Vector 类型,并且只使用它的 xy
,但这会导致不清楚 UI,因为检查器中现在有两个未使用的元素,并且找不到 属性 属性或抽屉(例如 HideInInspector
)允许您对检查器隐藏 zw
值。
那么有没有办法使用 属性 类型公开 float2?或者,您可以在编辑器中将两个浮动属性彼此相邻放置,例如 Tiling/Offset 抽屉是标准 2D
属性 类型(可能类似于 [EditorGUILayout.BeginHorizontal][2]
)?
通过快速搜索,我发现有 MaterialPropertyDrawer
可以扩展以在着色器检查器中添加自定义标签(参考:https://docs.unity3d.com/ScriptReference/MaterialPropertyDrawer.html)。
因此,您可以在着色器中使用 Vector
属性,创建自定义属性,比方说,[ShowAsVector2]
并为其制作 MaterialPropertyDrawer
,这只会显示两个输入字段,并将它们的值分配给向量的 x
和 y
值。这将导致着色器 属性 写为:
[ShowAsVector2] _Position2D("Position", Vector) = (0, 0, 0, 0)
这是@tsvedas 回答的扩展。
using UnityEngine;
using UnityEditor;
/// <summary>
/// Draws a vector2 field for vector properties.
/// Usage: [ShowAsVector2] _Vector2("Vector 2", Vector) = (0,0,0,0)
/// </summary>
public class ShowAsVector2Drawer : MaterialPropertyDrawer
{
public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor)
{
if( prop.type == MaterialProperty.PropType.Vector )
{
EditorGUIUtility.labelWidth = 0f;
EditorGUIUtility.fieldWidth = 0f;
if (!EditorGUIUtility.wideMode)
{
EditorGUIUtility.wideMode = true;
EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - 212;
}
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
Vector4 vec = EditorGUI.Vector2Field(position, label, prop.vectorValue);
if (EditorGUI.EndChangeCheck()) {
prop.vectorValue = vec;
}
}
else
editor.DefaultShaderProperty( prop, label.text );
}
}
只需将此脚本放在 Editor 文件夹中,您应该只能看到 x 和 y 坐标。