diff --git a/Packages/src/Editor/AnimatablePropertyEditor.cs b/Packages/src/Editor/AnimatablePropertyEditor.cs index f3e5de1..b71db83 100644 --- a/Packages/src/Editor/AnimatablePropertyEditor.cs +++ b/Packages/src/Editor/AnimatablePropertyEditor.cs @@ -3,15 +3,19 @@ using System.Linq; using System.Text; using UnityEditor; using UnityEngine; +using ShaderPropertyType = Coffee.UIExtensions.AnimatableProperty.ShaderPropertyType; namespace Coffee.UIExtensions { internal static class AnimatablePropertyEditor { private static readonly GUIContent s_ContentNothing = new GUIContent("Nothing"); + private static readonly GUIContent s_ContentCustom = new GUIContent("Add Custom..."); private static readonly List s_ActiveNames = new List(); private static readonly StringBuilder s_Sb = new StringBuilder(); private static readonly HashSet s_Names = new HashSet(); + private static ShaderProperty s_CustomProperty = new ShaderProperty("", ShaderPropertyType.None); + private static bool s_ShowCustomProperty = false; private static string CollectActiveNames(SerializedProperty sp, List result) { @@ -51,8 +55,19 @@ namespace Coffee.UIExtensions ? "-" : CollectActiveNames(sp, s_ActiveNames); - if (!GUI.Button(rect, text, EditorStyles.popup)) return; + if (GUI.Button(rect, text, EditorStyles.popup)) + { + ShowMenu(sp, mats); + } + if (s_ShowCustomProperty) + { + DrawCustomProperty(sp, ref s_CustomProperty); + } + } + + private static void ShowMenu(SerializedProperty sp, List mats) + { var gm = new GenericMenu(); gm.AddItem(s_ContentNothing, s_ActiveNames.Count == 0, x => { @@ -61,13 +76,20 @@ namespace Coffee.UIExtensions current.serializedObject.ApplyModifiedProperties(); }, sp); + gm.AddItem(s_ContentCustom, s_ShowCustomProperty, () => + { + s_ShowCustomProperty = !s_ShowCustomProperty; + s_CustomProperty.Reset(); + }); + gm.AddSeparator(""); + if (!sp.hasMultipleDifferentValues) { for (var i = 0; i < sp.arraySize; i++) { var p = sp.GetArrayElementAtIndex(i); var name = p.FindPropertyRelative("m_Name").stringValue; - var type = (AnimatableProperty.ShaderPropertyType)p.FindPropertyRelative("m_Type").intValue; + var type = (ShaderPropertyType)p.FindPropertyRelative("m_Type").intValue; AddMenu(gm, sp, new ShaderProperty(name, type), false); } } @@ -86,16 +108,16 @@ namespace Coffee.UIExtensions { #if UNITY_6000_5_OR_NEWER var name = mat.shader.GetPropertyName(i); - var type = (AnimatableProperty.ShaderPropertyType)mat.shader.GetPropertyType(i); + var type = (ShaderPropertyType)mat.shader.GetPropertyType(i); #else var name = ShaderUtil.GetPropertyName(mat.shader, i); - var type = (AnimatableProperty.ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i); + var type = (ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i); #endif if (!s_Names.Add(name)) continue; AddMenu(gm, sp, new ShaderProperty(name, type), true); - if (type != AnimatableProperty.ShaderPropertyType.Texture) continue; + if (type != ShaderPropertyType.Texture) continue; AddMenu(gm, sp, new ShaderProperty($"{name}_ST"), true); AddMenu(gm, sp, new ShaderProperty($"{name}_HDR"), true); @@ -111,41 +133,82 @@ namespace Coffee.UIExtensions if (add && s_ActiveNames.Contains(prop.name)) return; var label = new GUIContent($"{prop.name} ({prop.type})"); - menu.AddItem(label, s_ActiveNames.Contains(prop.name), () => - { - var index = s_ActiveNames.IndexOf(prop.name); - if (0 <= index) - { - sp.DeleteArrayElementAtIndex(index); - } - else - { - sp.InsertArrayElementAtIndex(sp.arraySize); - var p = sp.GetArrayElementAtIndex(sp.arraySize - 1); - p.FindPropertyRelative("m_Name").stringValue = prop.name; - p.FindPropertyRelative("m_Type").intValue = (int)prop.type; - } + menu.AddItem(label, s_ActiveNames.Contains(prop.name), () => AddProp(sp, prop)); + } - sp.serializedObject.ApplyModifiedProperties(); - }); + private static void DrawCustomProperty(SerializedProperty sp, ref ShaderProperty prop) + { + var r = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight + 8); + r.xMin += 60; + GUI.Label(r, (Texture)null, EditorStyles.helpBox); + + r = new Rect(r.x + 4, r.y + 4, r.width - 8 - 100 - 16, r.height - 8); + prop.name = EditorGUI.TextField(r, prop.name); + r.x += r.width + 2; + r.width = 100 - 2; + prop.type = (ShaderPropertyType)EditorGUI.EnumPopup(r, prop.type); + r.x += r.width; + r.width = 16; + + EditorGUI.BeginDisabledGroup(!prop.IsValid(s_ActiveNames)); + if (GUI.Button(r, EditorGUIUtility.IconContent("Toolbar Plus"), EditorStyles.label)) + { + GUI.FocusControl(""); + AddProp(sp, prop); + prop.Reset(); + } + + EditorGUI.EndDisabledGroup(); + } + + private static void AddProp(SerializedProperty sp, ShaderProperty prop) + { + var index = s_ActiveNames.IndexOf(prop.name); + if (0 <= index) + { + sp.DeleteArrayElementAtIndex(index); + } + else + { + sp.InsertArrayElementAtIndex(sp.arraySize); + var p = sp.GetArrayElementAtIndex(sp.arraySize - 1); + p.FindPropertyRelative("m_Name").stringValue = prop.name; + p.FindPropertyRelative("m_Type").intValue = (int)prop.type; + } + + sp.serializedObject.ApplyModifiedProperties(); } private struct ShaderProperty { - public readonly string name; - public readonly AnimatableProperty.ShaderPropertyType type; + public string name; + public ShaderPropertyType type; public ShaderProperty(string name) { this.name = name; - type = AnimatableProperty.ShaderPropertyType.Vector; + type = ShaderPropertyType.Vector; } - public ShaderProperty(string name, AnimatableProperty.ShaderPropertyType type) + public ShaderProperty(string name, ShaderPropertyType type) { this.name = name; this.type = type; } + + public void Reset() + { + name = ""; + type = ShaderPropertyType.None; + } + + public bool IsValid(List activeNames) + { + if (string.IsNullOrEmpty(name)) return false; + if (type == ShaderPropertyType.None) return false; + if (activeNames.Contains(name)) return false; + return true; + } } } } diff --git a/Packages/src/README.md b/Packages/src/README.md index 76766be..d5c6271 100644 --- a/Packages/src/README.md +++ b/Packages/src/README.md @@ -164,6 +164,12 @@ _This package requires **Unity 2018.3 or later**._ - **Scale**: Scale the rendering particles. When the `3D` toggle is enabled, 3D scale (x, y, z) is supported. - **Animatable Properties**: If you want to update material properties (e.g., `_MainTex_ST`, `_Color`) in AnimationClip, use this to mark as animatable. + +> [!TIPS] +> (Unity 2021.1 or later) **Custom Animatable Properties** +> From the `Add Custom...` menu in `Animatable Properties`, you can add fields located outside the `Properties` block in the shader as `Animatable Properties`. +> This allows `Matrix`, `Matrix Array`, `Float Array`, and `Vector Array` values modified by the `ParticleSystemRenderer.SetPropertyBlock` method to be automatically reflected in UIParticle. + - **Mesh Sharing**: Particle simulation results are shared within the same group. A large number of the same effects can be displayed with a small load. When the `Random` toggle is enabled, it will be grouped randomly. - **None:** Disable mesh sharing. diff --git a/Packages/src/Runtime/AnimatableProperty.cs b/Packages/src/Runtime/AnimatableProperty.cs index bbcbe65..ede5c5d 100644 --- a/Packages/src/Runtime/AnimatableProperty.cs +++ b/Packages/src/Runtime/AnimatableProperty.cs @@ -8,11 +8,18 @@ namespace Coffee.UIExtensions { public enum ShaderPropertyType { + None = -1, Color, Vector, Float, Range, - Texture + Texture, + Int, + + Matrix = 100, + MatrixArray = 101, + FloatArray = 102, + VectorArray = 103, } [SerializeField] private string m_Name = ""; @@ -32,7 +39,11 @@ namespace Coffee.UIExtensions public void UpdateMaterialProperties(Material material, MaterialPropertyBlock mpb) { +#if UNITY_2021_1_OR_NEWER + if (!mpb.HasProperty(id)) return; +#else if (!material.HasProperty(id)) return; +#endif switch (type) { @@ -49,6 +60,21 @@ namespace Coffee.UIExtensions case ShaderPropertyType.Texture: material.SetTexture(id, mpb.GetTexture(id)); break; + case ShaderPropertyType.Int: + material.SetInt(id, mpb.GetInt(id)); + break; + case ShaderPropertyType.Matrix: + material.SetMatrix(id, mpb.GetMatrix(id)); + break; + case ShaderPropertyType.MatrixArray: + material.SetMatrixArray(id, mpb.GetMatrixArray(id)); + break; + case ShaderPropertyType.FloatArray: + material.SetFloatArray(id, mpb.GetFloatArray(id)); + break; + case ShaderPropertyType.VectorArray: + material.SetVectorArray(id, mpb.GetVectorArray(id)); + break; } } } diff --git a/Packages/src/Samples~/Demo/Animations/ColorArrayInjection.cs b/Packages/src/Samples~/Demo/Animations/ColorArrayInjection.cs new file mode 100644 index 0000000..c628506 --- /dev/null +++ b/Packages/src/Samples~/Demo/Animations/ColorArrayInjection.cs @@ -0,0 +1,32 @@ +using System.Linq; +using UnityEngine; + +[RequireComponent(typeof(ParticleSystemRenderer))] +public class ColorArrayInjection : MonoBehaviour +{ + [SerializeField] private string m_PropertyName = "_Color2"; + + [SerializeField] private Color[] m_Colors = new Color[4] + { + Color.red, + Color.green, + Color.blue, + Color.yellow + }; + + private void OnEnable() + { + if (TryGetComponent(out var psr)) + { + var mpb = new MaterialPropertyBlock(); + psr.GetPropertyBlock(mpb); + mpb.SetVectorArray(m_PropertyName, m_Colors.Select(x => new Vector4(x.r, x.g, x.b, 1.0f)).ToArray()); + psr.SetPropertyBlock(mpb); + } + } + + private void OnValidate() + { + OnEnable(); + } +} diff --git a/Packages/src/Samples~/Demo/Animations/ColorArrayInjection.cs.meta b/Packages/src/Samples~/Demo/Animations/ColorArrayInjection.cs.meta new file mode 100644 index 0000000..16c9c9c --- /dev/null +++ b/Packages/src/Samples~/Demo/Animations/ColorArrayInjection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: da4c2e90ecd3d4dd4a520099c08cf493 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Samples~/Demo/Materials/UIAdditive+Color.shader b/Packages/src/Samples~/Demo/Materials/UIAdditive+Color.shader new file mode 100644 index 0000000..8234412 --- /dev/null +++ b/Packages/src/Samples~/Demo/Materials/UIAdditive+Color.shader @@ -0,0 +1,160 @@ +Shader "UI/Additive And Color" +{ + Properties + { + _MainTex ("Sprite Texture", 2D) = "white" {} + _Color ("Tint", Color) = (1,1,1,1) + + _StencilComp ("Stencil Comparison", Float) = 8 + _Stencil ("Stencil ID", Float) = 0 + _StencilOp ("Stencil Operation", Float) = 0 + _StencilWriteMask ("Stencil Write Mask", Float) = 255 + _StencilReadMask ("Stencil Read Mask", Float) = 255 + + _ColorMask ("Color Mask", Float) = 15 + + [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 + } + + SubShader + { + Tags + { + "Queue"="Transparent" + "IgnoreProjector"="True" + "RenderType"="Transparent" + "PreviewType"="Plane" + "CanUseSpriteAtlas"="True" + } + + Stencil + { + Ref [_Stencil] + Comp [_StencilComp] + Pass [_StencilOp] + ReadMask [_StencilReadMask] + WriteMask [_StencilWriteMask] + } + + Cull Off + Lighting Off + ZWrite Off + ZTest [unity_GUIZTestMode] + Fog { Mode Off } + Blend One One + ColorMask [_ColorMask] + + Pass + { + Name "Default" + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma target 2.0 + + #include "UnityCG.cginc" + #include "UnityUI.cginc" + + #pragma multi_compile __ UNITY_UI_CLIP_RECT + #pragma multi_compile __ UNITY_UI_ALPHACLIP + + struct appdata_t + { + float4 vertex : POSITION; + float4 color : COLOR; + float2 texcoord : TEXCOORD0; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct v2f + { + float4 vertex : SV_POSITION; + fixed4 color : COLOR; + float2 texcoord : TEXCOORD0; + float4 worldPosition : TEXCOORD1; + float4 mask : TEXCOORD2; + UNITY_VERTEX_OUTPUT_STEREO + }; + + fixed4 _Color; + sampler2D _MainTex; + float4 _MainTex_ST; + fixed4 _TextureSampleAdd; + float4 _ClipRect; + float _UIMaskSoftnessX; + float _UIMaskSoftnessY; + int _UIVertexColorAlwaysGammaSpace; + #define LENGTH 4 + float4 _Color2[4]; + + half3 _UIGammaToLinear(half3 value) + { + half3 low = 0.0849710 * value - 0.000163029; + half3 high = value * (value * (value * 0.265885 + 0.736584) - 0.00980184) + 0.00319697; + + // We should be 0.5 away from any actual gamma value stored in an 8 bit channel + const half3 split = (half3)0.0725490; // Equals 18.5 / 255 + return (value < split) ? low : high; + } + + v2f vert(appdata_t v) + { + v2f OUT; + UNITY_SETUP_INSTANCE_ID(v); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); + float4 vPosition = UnityObjectToClipPos(v.vertex); + OUT.worldPosition = v.vertex; + OUT.vertex = vPosition; + + float2 pixelSize = vPosition.w; + pixelSize /= float2(1, 1) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy)); + + float4 clampedRect = clamp(_ClipRect, -2e10, 2e10); + float2 maskUV = (v.vertex.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy); + OUT.texcoord = TRANSFORM_TEX(v.texcoord.xy, _MainTex); + OUT.mask = float4(v.vertex.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * half2(_UIMaskSoftnessX, _UIMaskSoftnessY) + abs(pixelSize.xy))); + + if (_UIVertexColorAlwaysGammaSpace) + { + #ifndef UNITY_COLORSPACE_GAMMA + v.color.rgb = _UIGammaToLinear(v.color.rgb); + #endif + } + + OUT.color = v.color * _Color; + return OUT; + } + + fixed4 frag(v2f IN) : SV_Target + { + //Round up the alpha color coming from the interpolator (to 1.0/256.0 steps) + //The incoming alpha could have numerical instability, which makes it very sensible to + //HDR color transparency blend, when it blends with the world's texture. + const half alphaPrecision = half(0xff); + const half invAlphaPrecision = half(1.0 / alphaPrecision); + IN.color.a = round(IN.color.a * alphaPrecision) * invAlphaPrecision; + + half4 color = IN.color * (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd); + + #ifdef UNITY_UI_CLIP_RECT + half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(IN.mask.xy)) * IN.mask.zw); + color.a *= m.x * m.y; + #endif + + #ifdef UNITY_UI_ALPHACLIP + clip(color.a - 0.001); + #endif + + fixed3 fc = _Color2[floor(color.r*LENGTH-0.01)].rgb; + if (0.1 < fc.r || 0.1 < fc.g || 0.1 < fc.b) + { + color.rgb = fc; + } + color.rgb *= color.a; + + return color; + } + ENDCG + } + } +} \ No newline at end of file diff --git a/Packages/src/Samples~/Demo/Materials/UIAdditive+Color.shader.meta b/Packages/src/Samples~/Demo/Materials/UIAdditive+Color.shader.meta new file mode 100644 index 0000000..f2ff119 --- /dev/null +++ b/Packages/src/Samples~/Demo/Materials/UIAdditive+Color.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9cc9ed37ff19d40e684526abbc1d44a6 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Samples~/Demo/Materials/UIParticle_Demo_Animatable+Color.mat b/Packages/src/Samples~/Demo/Materials/UIParticle_Demo_Animatable+Color.mat new file mode 100644 index 0000000..b74852d --- /dev/null +++ b/Packages/src/Samples~/Demo/Materials/UIParticle_Demo_Animatable+Color.mat @@ -0,0 +1,90 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: UIParticle_Demo_Animatable+Color + m_Shader: {fileID: 4800000, guid: 9cc9ed37ff19d40e684526abbc1d44a6, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _ColorMask: 15 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _Stencil: 0 + - _StencilComp: 8 + - _StencilOp: 0 + - _StencilReadMask: 255 + - _StencilWriteMask: 255 + - _UVSec: 0 + - _UseUIAlphaClip: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Packages/src/Samples~/Demo/Materials/UIParticle_Demo_Animatable+Color.mat.meta b/Packages/src/Samples~/Demo/Materials/UIParticle_Demo_Animatable+Color.mat.meta new file mode 100644 index 0000000..175a639 --- /dev/null +++ b/Packages/src/Samples~/Demo/Materials/UIParticle_Demo_Animatable+Color.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 81f29a831022a4756b17daa366d67e10 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Samples~/Demo/Materials/UIParticle_Demo_Animatable.mat b/Packages/src/Samples~/Demo/Materials/UIParticle_Demo_Animatable.mat index 78a38fd..5681995 100644 --- a/Packages/src/Samples~/Demo/Materials/UIParticle_Demo_Animatable.mat +++ b/Packages/src/Samples~/Demo/Materials/UIParticle_Demo_Animatable.mat @@ -8,8 +8,8 @@ Material: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: UIParticle_Demo_Animatable - m_Shader: {fileID: 4800000, guid: ecfa8f5732b504ef98fba10aa18d0326, type: 3} - m_ShaderKeywords: + m_Shader: {fileID: 4800000, guid: 9cc9ed37ff19d40e684526abbc1d44a6, type: 3} + m_Parent: {fileID: 0} m_LightmapFlags: 4 m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 diff --git a/Packages/src/Samples~/Demo/Prefabs/UIParticle_Demo_Animatable.prefab b/Packages/src/Samples~/Demo/Prefabs/UIParticle_Demo_Animatable.prefab index affd98d..32cb58f 100644 --- a/Packages/src/Samples~/Demo/Prefabs/UIParticle_Demo_Animatable.prefab +++ b/Packages/src/Samples~/Demo/Prefabs/UIParticle_Demo_Animatable.prefab @@ -69,6 +69,8 @@ MonoBehaviour: m_AnimatableProperties: - m_Name: _MainTex_ST m_Type: 1 + - m_Name: _Color2 + m_Type: 103 m_Particles: - {fileID: 198637387440798640} m_MeshSharing: 0 @@ -88,6 +90,7 @@ GameObject: - component: {fileID: 199176884810573912} - component: {fileID: 222047182059782320} - component: {fileID: 95475093951880840} + - component: {fileID: 3543952012814938654} m_Layer: 0 m_Name: UvAnimParticle m_TagString: Untagged @@ -4864,3 +4867,21 @@ Animator: m_HasTransformHierarchy: 1 m_AllowConstantClipSamplingOptimization: 1 m_KeepAnimatorControllerStateOnDisable: 0 +--- !u!114 &3543952012814938654 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1349193913114882} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: da4c2e90ecd3d4dd4a520099c08cf493, type: 3} + m_Name: + m_EditorClassIdentifier: + m_PropertyName: _Color2 + m_Colors: + - {r: 1, g: 0, b: 0, a: 1} + - {r: 0, g: 1, b: 0, a: 1} + - {r: 0, g: 0, b: 1, a: 1} + - {r: 1, g: 0.92156863, b: 0.015686275, a: 1}