MaterialのShaderプロパティーを表示 その2(Editor拡張)
コントロールの作成
プロパティの表示に必要なデータの取得で取得したプロパティのタイプ(prop_type)を用いて、プロパティのタイプによって作成するコントロールを変更します。
1 2 3 4 5 6 |
ShaderUtil.ShaderPropertyType prop_type = ShaderUtil.GetPropertyType(target_shader, i); ・・・ switch (prop_type) { ・・・ } |
Colorプロパティ
colorプロパティに作用するAttributeはありません。そのため、以下に示すように色を選択するコントロールの作成のみを行っています。
1 2 3 4 5 |
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を選択するコントロールの作成のみを行っています。
1 2 3 4 |
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によってコントロールの表示方法などを変更します。
1 2 3 |
case ShaderUtil.ShaderPropertyType.Float: ・・・ break; |
Toggle
AttributeにToggleもしくはMaterialToggleが指定されていた場合、FloatプロパティはToggleで表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
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)へ変換します。
1 2 3 4 |
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によってプロパティ名を大文字へ変更しています。
1 2 3 4 5 6 7 8 9 10 11 12 |
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とすることでコントロールが作成されたことを知らせます。
1 2 3 4 5 6 7 8 9 10 11 12 |
else { if (flg) { target_mat.EnableKeyword(param[j]); } else { target_mat.DisableKeyword(param[j]); } } control_created = true; |
Enum
FloatプロパティのAttributeにEnumを指定することができます。Enumはキーワードを指定すると、そのキーワードに指定されている数値を設定することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
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プロパティを表示します。
1 2 3 4 |
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で受け取ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
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とすることでコントロールが作成されたことを知らせます。
1 2 3 4 5 |
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から有効なバリアントのキーワードを変更することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
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を分割します。
1 2 3 4 5 |
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用のコントロールを作成します。
1 2 3 4 |
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とすることでコントロールが作成されたことを知らせます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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により変更された数値をマテリアルへ渡します。
1 2 3 4 5 6 7 |
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によってコントロールの表示方法などを変更します。
1 2 3 |
case ShaderUtil.ShaderPropertyType.Range: ・・・ break; |
PowerSlider
RangeプロパティのAttributeにはPowerSliderを指定することができます。Shaderには[PowerSlider(数値)]と記述されます。paramには括弧内の数値がstring型で入っています。よって、これをfloat.Parseを用いてfloat型へ変換します。もし、変換できなかった場合は処理を飛ばし、次のAttributeの処理を行います。変換できた場合はPowerSliderを作成し、最後に、control_created=trueとすることでコントロールが作成されたことを知らせます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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とすることでコントロールが作成されたことを知らせます。
1 2 3 4 5 6 |
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のありなしの処理を分けています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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用のコントロールを作成しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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用コントロールを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
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はコンメントアウト部分に記述しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
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を作成しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
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
コメントを書く