MaterialのShaderプロパティーを表示 その2(Editor拡張)
コントロールの作成
プロパティの表示に必要なデータの取得で取得したプロパティのタイプ(prop_type)を用いて、プロパティのタイプによって作成するコントロールを変更します。
ShaderUtil.ShaderPropertyType prop_type = ShaderUtil.GetPropertyType(target_shader, i);
・・・
switch (prop_type)
{
・・・
}
Colorプロパティ
colorプロパティに作用するAttributeはありません。そのため、以下に示すように色を選択するコントロールの作成のみを行っています。
case ShaderUtil.ShaderPropertyType.Color:
Color col = CustomEditorGUI.ColorField(description, target_mat.GetColor(prop_name), style_label);
target_mat.SetColor(prop_name, col);
break;
Vectorプロパティ
Vectorプロパティもcolorプロパティと同様にAttributeはありません。そのため、Vectorを選択するコントロールの作成のみを行っています。
case ShaderUtil.ShaderPropertyType.Vector:
Vector4 vec = CustomEditorGUI.Vector4Field(description, target_mat.GetVector(prop_name), style_label, style_text_field, event_current);
target_mat.SetVector(prop_name, vec);
break;
Floatプロパティ
Floatプロパティに有効なAttributeはToggle、Enum及びKeywordEnumがあります。これらが指定されて場合、Attributeによってコントロールの表示方法などを変更します。
case ShaderUtil.ShaderPropertyType.Float:
・・・
break;
Toggle
AttributeにToggleもしくはMaterialToggleが指定されていた場合、FloatプロパティはToggleで表示されます。
if (attribs[j] == "Toggle" || attribs[j] == "MaterialToggle")
{
val = target_mat.GetFloat(prop_name);
bool flg = (val != 0) ? true : false; //shaderから得られた数値によりbool
flg = CustomEditorGUI.Toggle(description, flg, style_label, style_toggle);
val = (flg) ? 1 : 0; //コントロールで変更されたboolに応じて数値を決定
//キーワードが設定されてない場合
if (param[j] == null)
{
if (flg)
{
target_mat.EnableKeyword(prop_name.ToUpper() + "_ON");
}
else
{
target_mat.DisableKeyword(prop_name.ToUpper() + "_ON");
}
}
//キーワードが設定されている場合
else
{
if (flg)
{
target_mat.EnableKeyword(param[j]);
}
else
{
target_mat.DisableKeyword(param[j]);
}
}
control_created = true;
break;
}
GetFloatによりプロパティの数値を取得します。取得した数値をbool型へ変換します。(0→false、0以外→true)このbool値を用いてToggleを作成します。Toggleの結果はそのままshaderへ渡すことができないので、bool値に応じた数値(true→1、false→0)へ変換します。
val = target_mat.GetFloat(prop_name);
bool flg = (val != 0) ? true : false;
flg = CustomEditorGUI.Toggle(description, flg, style_label, style_toggle);
val = (flg) ? 1 : 0;
Attributeが[Toggle]または[MaterialToggle]であった場合、プロパティ名_ONのようなキーワードを用いてバリアントを作成できます。よって、Toggleから取得したbool値を用いてキーワードの状態を変更します。また、キーワードは全て大文字にしなければならないのでstring.ToUpperによってプロパティ名を大文字へ変更しています。
if (param[j] == null)
{
if (flg)
{
target_mat.EnableKeyword(prop_name.ToUpper() + "_ON");
}
else
{
target_mat.DisableKeyword(prop_name.ToUpper() + "_ON");
}
}
Attributeが[Toggle(param)]であった場合、バリアントのキーワードにparamを使用することができます。よって、以下のようにparamでキーワードの状態を変更しています。最後に、control_created=trueとすることでコントロールが作成されたことを知らせます。
else
{
if (flg)
{
target_mat.EnableKeyword(param[j]);
}
else
{
target_mat.DisableKeyword(param[j]);
}
}
control_created = true;
Enum
FloatプロパティのAttributeにEnumを指定することができます。Enumはキーワードを指定すると、そのキーワードに指定されている数値を設定することができます。
else if (attribs[j] == "Enum")
{
val = target_mat.GetFloat(prop_name);
string temp = Regex.Replace(param[j], @"\s", ""); //スペースの削除
string[] enum_temp = temp.Split(',');
if (enum_temp.Length % 2 != 0) break; //名前と数値が組になっていない場合は無効なAttributeとして処理する。
int enum_length = enum_temp.Length / 2;
//名前と数値に分ける。数値部分の文字がfloatへ変更できなかった場合は無効なAttributeとして処理する。
string[] enum_name = new string[enum_length];
float[] enum_value = new float[enum_length];
bool error = false;
int selected = 0;
for (int k = 0; k < enum_length; k++)
{
enum_name[k] = enum_temp[k * 2];
try
{
enum_value[k] = float.Parse(enum_temp[k * 2 + 1]);
}
catch
{
error = true;
}
if (val == enum_value[k])
{
selected = k;
}
}
if (error) continue;
//Enumの表示
selected = EditorPopUpWindow.Create(description, selected, enum_name, style_label, style_button, style_popup_label, color_popup_background, PopUpPosition.Center, this);
val = enum_value[selected];
control_created = true;
break;
}
EnumのAttributeは[Enum(ZERO, 0, HALF, 0.5, ONE, 1)]のように記述されています。よって取得したparam(ZERO, 0, HALF, 0.5, ONE, 1)をキーワードと数値へ分ける必要があります。始めに、空白の削除を行い、カンマによって文字列を分割します。次に、取得したparamが妥当か検討します。名前と数値が組となっている場合は、分割された文字列(enum_temp)の数は偶数となるはずです。よって、偶数でなかった場合は正しくAttributeが記述できていません。この場合は、breakにより処理を抜け、通常のFloatプロパティを表示します。
string temp = Regex.Replace(param[j], @"\s", "");
string[] enum_temp = temp.Split(',');
if (enum_temp.Length % 2 != 0) break;
次に、分割した文字列をキーワードと数値へ分けます。数値部分はstring型で取得しているのでfloat.Parseを用いてfloat型へ変換します。float型へ変更できなかった場合はerror=trueとすることで処理を抜け、次のAttributeの処理を行います。また、選択されているキーワードの順番をselectedで受け取ります。
string[] enum_name = new string[enum_length];
float[] enum_value = new float[enum_length];
bool error = false;
int selected = 0;
for (int k = 0; k < enum_length; k++)
{
enum_name[k] = enum_temp[k * 2];
try
{
enum_value[k] = float.Parse(enum_temp[k * 2 + 1]);
}
catch
{
error = true;
}
if (val == enum_value[k])
{
selected = k;
}
}
if (error) continue;
これらのキーワードと数値を用いてEnum用のコントロールを作成ます。また、選択されたキーワードの数値をvalへ代入し、後にマテリアルへ渡します。最後に、control_created=trueとすることでコントロールが作成されたことを知らせます。
selected = EditorPopUpWindow.Create(description, selected, enum_name, style_label, style_button, style_popup_label, color_popup_background, PopUpPosition.Center, this);
val = enum_value[selected];
control_created = true;
KeywordEnum
AttributeにKeywordEnumを指定することでUIから有効なバリアントのキーワードを変更することができます。
else if (attribs[j] == "KeywordEnum")
{
val = target_mat.GetFloat(prop_name);
string temp = Regex.Replace(param[j], @"\s", "");
string[] enum_name = temp.Split(',');
int selected = (int)val;
selected = EditorPopUpWindow.Create(description, selected, enum_name, style_label, style_button, style_popup_label, PopUpPosition.Center, this);
val = selected;
//有効にするキーワード以外はDisableで無効にする必要がある
target_mat.SetFloat(prop_name, selected);
for (int k = 0; k < enum_name.Length; k++)
{
if (k == selected)
{
target_mat.EnableKeyword(prop_name.ToUpper() + "_" + enum_name[k].ToUpper());
}
else
{
target_mat.DisableKeyword(prop_name.ToUpper() + "_" + enum_name[k].ToUpper());
}
}
control_created = true;
break;
Enumの場合と同様に、空白を削除した後にカンマによってparamを分割します。
val = target_mat.GetFloat(prop_name);
string temp = Regex.Replace(param[j], @"\s", "");
string[] enum_name = temp.Split(',');
プロパティより得られる数値は、選択されているキーワードの番号となります。[KeywordEnum(Red, Green, Blue)]の場合は、Redは0、Greenは1、Blueは2となります。よって、取得した文字列と数値を用いてKeywordEnum用のコントロールを作成します。
int selected = (int)val;
selected = EditorPopUpWindow.Create(description, selected, enum_name, style_label, style_button, style_popup_label, PopUpPosition.Center, this);
val = selected;
選択された番号をマテリアルへ渡し、選択されたキーワードを有効にします。この際、選択されなかったキーワードは無効にする必要があります。最後に、control_created=trueとすることでコントロールが作成されたことを知らせます。
target_mat.SetFloat(prop_name, selected);
for (int k = 0; k < enum_name.Length; k++)
{
if (k == selected)
{
target_mat.EnableKeyword(prop_name.ToUpper() + "_" + enum_name[k].ToUpper());
}
else
{
target_mat.DisableKeyword(prop_name.ToUpper() + "_" + enum_name[k].ToUpper());
}
}
control_created = true;
Float
Attributeが無効もしくは指定されていない場合は、通常のFloatプロパティを作成します。最後に、material.SetFloatにより変更された数値をマテリアルへ渡します。
if (control_created == false)
{
val = CustomEditorGUI.FloatField(description, target_mat.GetFloat(prop_name), style_label, style_text_field, event_current);
}
target_mat.SetFloat(prop_name, val);
Rangeプロパティ
RangeプロパティはPowerSliderとIntRangeをAttributeへ指定できます。これらが指定された場合、Attributeによってコントロールの表示方法などを変更します。
case ShaderUtil.ShaderPropertyType.Range:
・・・
break;
PowerSlider
RangeプロパティのAttributeにはPowerSliderを指定することができます。Shaderには[PowerSlider(数値)]と記述されます。paramには括弧内の数値がstring型で入っています。よって、これをfloat.Parseを用いてfloat型へ変換します。もし、変換できなかった場合は処理を飛ばし、次のAttributeの処理を行います。変換できた場合はPowerSliderを作成し、最後に、control_created=trueとすることでコントロールが作成されたことを知らせます。
if (attribs[j] == "PowerSlider")
{
try
{
power = float.Parse(param[j]);
}
catch
{
continue;
}
slider_val = target_mat.GetFloat(prop_name);
slider_val = CustomEditorGUI.PowerSlider(description, slider_val, min, max, power, style_label, style_slider, style_slider_thumb, style_text_field, event_current);
slider_created = true;
break;
}
IntRnage
AttributeにIntRangeが指定されていた場合、IntSliderを作成します。今までと同様に、control_created=trueとすることでコントロールが作成されたことを知らせます。
else if (attribs[j] == "IntRange")
{
slider_val = CustomEditorGUI.IntSlider(description, (int)slider_val, (int)min, (int)max, style_label, style_slider, style_slider_thumb, style_text_field, event_current);
slider_created = true;
break;
}
Textureプロパティ
TextureプロパティにはNoScaleOffsetを指定することができます。このAttributeを指定すると、TextureプロパティのScaleとOffsetを非表示にすることができます。NoScaleOffsetはshader.GetPropertyFlagsより取得することができます。この結果より、ScaleとOffsetのありなしの処理を分けています。
case ShaderUtil.ShaderPropertyType.TexEnv:
//Texture
UnityEngine.Rendering.TextureDimension textureDimension = target_shader.GetPropertyTextureDimension(index);
if ((target_shader.GetPropertyFlags(index) & UnityEngine.Rendering.ShaderPropertyFlags.NoScaleOffset) == UnityEngine.Rendering.ShaderPropertyFlags.NoScaleOffset)
{
・・・
}
else
{
・・・
}
break;
NoScaleOffset
AttributeにNoScaleOffsetがあるTextureプロパティの処理です。TextureにはTexture、Cube、Texture3D及びTexture2DArrayがあります。よって、Textureの種類ごとにScale及びOffsetを表示しないTexture用のコントロールを作成しています。
if ((target_shader.GetPropertyFlags(index) & UnityEngine.Rendering.ShaderPropertyFlags.NoScaleOffset) == UnityEngine.Rendering.ShaderPropertyFlags.NoScaleOffset)
{
switch (textureDimension)
{
case UnityEngine.Rendering.TextureDimension.Tex2D:
Texture tex = CustomEditorGUI.TextureField(description, target_mat.GetTexture(prop_name), style_label);
target_mat.SetTexture(prop_name, tex);
break;
case UnityEngine.Rendering.TextureDimension.Cube:
Cubemap cubemap = CustomEditorGUI.CubemapField(description, target_mat.GetTexture(prop_name) as Cubemap, style_label);
target_mat.SetTexture(prop_name, cubemap);
break;
case UnityEngine.Rendering.TextureDimension.Tex3D:
Texture3D tex3d = CustomEditorGUI.VolumeTextureField(description, target_mat.GetTexture(prop_name) as Texture3D, style_label);
target_mat.SetTexture(prop_name, tex3d);
break;
case UnityEngine.Rendering.TextureDimension.Tex2DArray:
Texture2DArray tex2darray = CustomEditorGUI.Texture2DArrayField(description, target_mat.GetTexture(prop_name) as Texture2DArray, style_label);
target_mat.SetTexture(prop_name, tex2darray);
break;
}
}
NoScaleOffsetがない場合
TextureプロパティにNoScaleOffsetがない場合の処理です。Scale及びOffsetを表示するTexture用コントロールを作成します。
else
{
Vector2 scale = target_mat.GetTextureScale(prop_name);
Vector2 offset = target_mat.GetTextureOffset(prop_name);
switch (textureDimension)
{
case UnityEngine.Rendering.TextureDimension.Tex2D:
Texture tex = CustomEditorGUI.TextureField(description, target_mat.GetTexture(prop_name), style_label, style_text_field, ref scale, ref offset, event_current);
target_mat.SetTexture(prop_name, tex);
break;
case UnityEngine.Rendering.TextureDimension.Cube:
Cubemap cubemap = CustomEditorGUI.CubemapField(description, target_mat.GetTexture(prop_name) as Cubemap, style_label, style_text_field, ref scale, ref offset, event_current);
target_mat.SetTexture(prop_name, cubemap);
break;
case UnityEngine.Rendering.TextureDimension.Tex3D:
Texture3D tex3d = CustomEditorGUI.VolumeTextureField(description, target_mat.GetTexture(prop_name) as Texture3D, style_label, style_text_field, ref scale, ref offset, event_current);
target_mat.SetTexture(prop_name, tex3d);
break;
case UnityEngine.Rendering.TextureDimension.Tex2DArray:
Texture2DArray tex2darray = CustomEditorGUI.Texture2DArrayField(description, target_mat.GetTexture(prop_name) as Texture2DArray, style_label, style_text_field, ref scale, ref offset, event_current);
target_mat.SetTexture(prop_name, tex2darray);
break;
}
target_mat.SetTextureScale(prop_name, scale);
target_mat.SetTextureOffset(prop_name, offset);
}
実行結果
作成したMaterialのShaderプロパティを表示するコードは以下のScriptで実行できます。以下のScriptではLightSkinが適用されます。DarkSkinはコンメントアウト部分に記述しています。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Text.RegularExpressions;
public class MaterialProperty : EditorWindow
{
private const string dark_skin_path = "builtin skins/darkskin/images/";
private Material target_mat;
private Vector2 scroll_shader = Vector2.zero;
private GUIStyle style_label, style_text_field, style_slider, style_slider_thumb, style_toggle, style_drop_button,
style_header, style_popup_label, style_obj;
private Texture2D tex_background;
private Color color_background = new Color(0.2f, 0.2f, 0.2f, 1.0f);
private Color color_popup_background = new Color(0.8f, 0.8f, 0.8f, 1.0f);
[MenuItem("Tools/MaterialProperty")]
public static void OpenWindow()
{
EditorWindow ed = EditorWindow.GetWindow(typeof(MaterialProperty), false, "MaterialProperty");
ed.minSize = new Vector2(285, 256);
ed.wantsMouseMove = true;
}
private void OnEnable()
{
//GUIStyle
//dark style
//GUISkin dark_skin = (GUISkin)EditorGUIUtility.Load("DarkSkin.guiskin");
//style_label = new GUIStyle(dark_skin.label);
//style_label.focused.textColor = new Color(0.506f, 0.706f, 1f, 1f);
//style_label.padding = new RectOffset(1, 1, 0, 0);
//style_text_field = new GUIStyle(dark_skin.textField);
//style_text_field.normal.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "textfield.png");
//style_text_field.focused.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "textfield focused.png");
//style_slider = new GUIStyle(dark_skin.horizontalSlider);
//style_slider_thumb = new GUIStyle(dark_skin.horizontalScrollbarThumb);
//style_toggle = new GUIStyle(dark_skin.toggle);
//style_toggle.normal.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "toggle.png");
//style_toggle.focused.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "toggle focus.png");
//style_toggle.active.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "toggle act.png");
//style_toggle.onNormal.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "toggle on.png");
//style_toggle.onFocused.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "toggle on focus.png");
//style_toggle.onActive.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "toggle on act.png");
//style_drop_button = new GUIStyle(dark_skin.button);
//style_drop_button.alignment = TextAnchor.MiddleLeft;
//style_drop_button.padding = new RectOffset(5, 2, 1, 2);
//style_drop_button.normal.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "btn.png");
//style_drop_button.focused.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "btn focus.png");
//style_drop_button.active.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "btn act.png");
//style_drop_button.onNormal.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "btn on.png");
//style_drop_button.onFocused.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "btn on focus.png");
//style_drop_button.onActive.background = (Texture2D)EditorGUIUtility.Load(dark_skin_path + "btn onact.png");
//style_header = new GUIStyle(style_label);
//style_header.fontStyle = FontStyle.Bold;
//style_obj = new GUIStyle(dark_skin.FindStyle("ObjectField"));
//light style
GUISkin light_skin = (GUISkin)EditorGUIUtility.Load("LightSkin.guiskin");
style_label = new GUIStyle(light_skin.label);
style_label.focused.textColor = new Color(0, 0.235f, 0.533f, 1f);
style_label.padding = new RectOffset(1, 1, 0, 0);
style_text_field = new GUIStyle(light_skin.textField);
style_slider = new GUIStyle(light_skin.horizontalSlider);
style_slider_thumb = new GUIStyle(light_skin.horizontalSliderThumb);
style_toggle = new GUIStyle(light_skin.toggle);
style_drop_button = new GUIStyle(light_skin.FindStyle("DropDownButton"));
style_drop_button.alignment = TextAnchor.MiddleLeft;
style_drop_button.padding = new RectOffset(5, 2, 1, 2);
style_header = new GUIStyle(style_label);
style_header.fontStyle = FontStyle.Bold;
style_popup_label = new GUIStyle(style_label);
style_obj = new GUIStyle(light_skin.FindStyle("ObjectField"));
//背景用画像
tex_background = new Texture2D(1, 1, TextureFormat.RGB24, false);
tex_background.SetPixel(0, 0, color_background);
tex_background.Apply();
}
private void OnGUI()
{
//GUI.DrawTexture(new Rect(0, 0, position.width, position.height), tex_background, ScaleMode.StretchToFill);
target_mat = (Material)CustomEditorGUI.ObjectField("target_mat", target_mat, typeof(Material), style_label, style_obj, false);
ShaderPropertyWindow();
}
void ShaderPropertyWindow()
{
・・・
}
private void DrawHeader(string label, GUIStyle style_header)
{
・・・
}
}
以上のScriptの動作を確認するために以下のShaderを作成しました。
Shader "Unlit/ShaderProperties"
{
Properties
{
[MainColor]
_MainColor ("main color", Color) = (0.3, 0.8, 0.6, 1.0)
_Color ("color", Color) = (0.3, 0.8, 0.6, 1.0)
_Float ("float", Float) = 2.3
[Space(aaa)] //()内が数値でなかった場合の確認用
[Header(Texture)]
_MainTex ("Texture", 2D) = "white" {}
_Rectangele ("Rectangle", Rect) = "white" {}
_Cubemap ("Cubemap", Cube) = "white" {}
_VolumeTex("3D Texture", 3D) = "white" {}
_Texture2DArray("Texture 2D Array", 2DArray) = "white" {}
[NoScaleOffset]
_MainTexS ("Texture", 2D) = "white" {}
[NoScaleOffset]
_CubemapS ("Cubemap", Cube) = "white" {}
[NoScaleOffset]
_VolumeTexS("3D Texture", 3D) = "white" {}
[NoScaleOffset]
_Texture2DArrayS("Texture 2D Array", 2DArray) = "white" {}
[Normal]
_NormalMap ("Normalmap", 2D) = "white" {}
[HDR]
_HDRTex ("HDR Texture", 2D) = "white" {}
[Header(Toggle)]
[Toggle]
_Toggle ("toggle", Int) = 0
[MaterialToggle]
_MaterialToggle ("material toggle", Int) = 0
[Toggle(ENABLE_INVERT)]
_Invert ("toggle", Int) = 0
[Header(Slider)]
_Range ("range", Range(-5.0, 5.0)) = 0.5
[HideInInspector]
_HideRange ("hide range", Range(0.0, 1.0)) = 0.5
[PowerSlider(0.5)]
_PowerSlider_1 ("PowerSlider(0, 1)", Range(0, 1)) = 0.5
[PowerSlider(0.5)]
_PowerSlider_2 ("PowerSlider(-1, 0)", Range(-5, 5)) = 0.5
[IntRange]
[PowerSlider(TWO)]
_ErrorPowerSlider ("ErrorSlider(-1, 0)", Range(-5, 5)) = 0.5
[IntRange]
_IntRange ("IntRange", Range(-5, 5)) = 0
_Vector ("vector", Vector) = (0.3, 3.7, 8.6, 7.1)
[Header(Enum)]
[Space]
[Space(100)]
[Enum(ZERO, 0, HALF, 0.5, ONE, 1)]
_Enum ("Enum", Float) = 0
[Toggle]
[Enum(test, 0, test2, 1)]
[KeywordEnum(Left, Right)]
_EnumTest ("EnumTest", Float) = 0
[KeywordEnum(Red, Green, Blue)]
_KeywordEnum ("KeywordEnum", Int) = 0
//()内が文字列と数値の組となっていない場合
[Enum(Left, 0, Right)]
_ErrorEnum1( "Error Enum1", Float) = 0
//()内が文字列だけの場合
[Enum(Left, ONE, Right, TWO)]
_ErrorEnum2 ("Error Enum2", Float) = 0
//不正なAttributeの後に処理できるかの確認用
[Enum(Left, 1, Right, 2)]
[Enum(Left, ONE, Right, TWO)]
_ErrorEnum3 ("Error Enum3", Float) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _KEYWORDENUM_RED _KEYWORDENUM_BLUE _KEYWORDENUM_GREEN
#pragma shader_feature _TOGGLE_ON _ _MATERIALTOGGLE_ON _ ENABLE_INVERT
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Enum;
int _Toggle;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
float3 result = float3(0, 0, 0);
#ifdef _KEYWORDENUM_RED
result = float3(1.0, 0, 0);
#elif _KEYWORDENUM_GREEN
result = float3(0, 1.0, 0.0);
#elif _KEYWORDENUM_BLUE
result = float3(0, 0.0, 1.0);
#endif
#ifdef _TOGGLE_ON
result = float3(1, 1, 0);
#endif
#ifdef _MATERIALTOGGLE_ON
result = float3(1, 0, 1);
#endif
#ifdef ENABLE_INVERT
result = float3(0, 1, 1);
#endif
col = fixed4(result, 1.0) * _Enum;
return col;
}
ENDCG
}
}
}
実行結果は以下の通りです。各コントロールの作成が問題なく行われていることが分かります。また、Toggleによるキーワードの状態の変更、Enumによる数値変更やKeywordEnumによるキーワードの変更が行えていることが分かります。
-
前の記事
MaterialのShaderプロパティーを表示 その1(Editor拡張) 2020.10.22
-
次の記事
検索機能付きポップアップウィンドウ(Editor拡張) 2020.11.01

コメントを書く