From a61fc6d0b36badb4b0666b6d2556828a7d97f81a Mon Sep 17 00:00:00 2001 From: ls9512 <598914653@qq.com> Date: Fri, 22 Mar 2024 18:03:20 +0800 Subject: [PATCH] Optimize property selection menu --- Editor/Script/BaseBinderEditor.cs | 8 +- Editor/Script/{Util.meta => GUI.meta} | 2 +- Editor/Script/GUI/EditorIcon.cs | 66 +++++++ Editor/Script/GUI/EditorIcon.cs.meta | 11 ++ Editor/Script/{Util => GUI}/EditorStyle.cs | 0 .../Script/{Util => GUI}/EditorStyle.cs.meta | 0 Editor/Script/GUI/GUIMenu.cs | 68 +++++++ Editor/Script/GUI/GUIMenu.cs.meta | 11 ++ Editor/Script/{Util => GUI}/GUIStruct.cs | 24 +++ Editor/Script/{Util => GUI}/GUIStruct.cs.meta | 0 .../{Util/EditorUtil.cs => GUI/GUIUtil.cs} | 184 +++--------------- .../GUIUtil.cs.meta} | 0 Editor/Script/GUI/Menu.meta | 8 + Editor/Script/GUI/Menu/ComponentsTreeMenu.cs | 118 +++++++++++ .../GUI/Menu/ComponentsTreeMenu.cs.meta | 11 ++ Editor/Script/GUI/Menu/PropertyMenu.cs | 55 ++++++ Editor/Script/GUI/Menu/PropertyMenu.cs.meta | 11 ++ Editor/Script/GUI/SearchableDropdown.meta | 8 + .../AdvancedDropdownExtensions.cs} | 36 +--- .../AdvancedDropdownExtensions.cs.meta | 11 ++ .../SearchableDropdown/SearchableDropdown.cs | 29 +++ .../SearchableDropdown.cs.meta | 2 +- .../SearchableDropdownItem.cs | 16 ++ .../SearchableDropdownItem.cs.meta | 11 ++ Editor/Script/PropertyBinderEditor.cs | 2 +- Editor/Script/TypeBinderEditor.cs | 8 +- .../Scene/UBind_Sample_02_TypeBInder.unity | 63 +++--- 27 files changed, 529 insertions(+), 234 deletions(-) rename Editor/Script/{Util.meta => GUI.meta} (77%) create mode 100644 Editor/Script/GUI/EditorIcon.cs create mode 100644 Editor/Script/GUI/EditorIcon.cs.meta rename Editor/Script/{Util => GUI}/EditorStyle.cs (100%) rename Editor/Script/{Util => GUI}/EditorStyle.cs.meta (100%) create mode 100644 Editor/Script/GUI/GUIMenu.cs create mode 100644 Editor/Script/GUI/GUIMenu.cs.meta rename Editor/Script/{Util => GUI}/GUIStruct.cs (91%) rename Editor/Script/{Util => GUI}/GUIStruct.cs.meta (100%) rename Editor/Script/{Util/EditorUtil.cs => GUI/GUIUtil.cs} (53%) rename Editor/Script/{Util/EditorUtil.cs.meta => GUI/GUIUtil.cs.meta} (100%) create mode 100644 Editor/Script/GUI/Menu.meta create mode 100644 Editor/Script/GUI/Menu/ComponentsTreeMenu.cs create mode 100644 Editor/Script/GUI/Menu/ComponentsTreeMenu.cs.meta create mode 100644 Editor/Script/GUI/Menu/PropertyMenu.cs create mode 100644 Editor/Script/GUI/Menu/PropertyMenu.cs.meta create mode 100644 Editor/Script/GUI/SearchableDropdown.meta rename Editor/Script/{SearchableDropdown.cs => GUI/SearchableDropdown/AdvancedDropdownExtensions.cs} (60%) create mode 100644 Editor/Script/GUI/SearchableDropdown/AdvancedDropdownExtensions.cs.meta create mode 100644 Editor/Script/GUI/SearchableDropdown/SearchableDropdown.cs rename Editor/Script/{ => GUI/SearchableDropdown}/SearchableDropdown.cs.meta (83%) create mode 100644 Editor/Script/GUI/SearchableDropdown/SearchableDropdownItem.cs create mode 100644 Editor/Script/GUI/SearchableDropdown/SearchableDropdownItem.cs.meta diff --git a/Editor/Script/BaseBinderEditor.cs b/Editor/Script/BaseBinderEditor.cs index 02ba95d..7d0d459 100644 --- a/Editor/Script/BaseBinderEditor.cs +++ b/Editor/Script/BaseBinderEditor.cs @@ -34,18 +34,18 @@ protected void DrawDataKey(SerializedProperty property) protected void DrawDirection(SerializedProperty property) { - EditorUtil.DrawToolbarEnum(property, typeof(DataDirection)); + GUIUtil.DrawToolbarEnum(property, typeof(DataDirection)); } protected void DrawTarget(SerializedProperty property, Transform root) where TComponent : Component { - EditorUtil.ComponentTreeMenu("Target", property, root); + GUIMenu.ComponentTreeMenu("Target", property, root); } public static void DrawTargetAndProperty(string targetPropertyName, SerializedProperty targetProperty, Transform parent, string propertyName, SerializedProperty property) where TComponent : Component { var originalTarget = targetProperty.objectReferenceValue; - EditorUtil.ComponentTreeMenu(targetPropertyName, targetProperty, parent, component => + GUIMenu.ComponentTreeMenu(targetPropertyName, targetProperty, parent, component => { // Auto Bind var change = originalTarget != targetProperty.objectReferenceValue && targetProperty.objectReferenceValue != null; @@ -65,7 +65,7 @@ public static void DrawTargetAndProperty(string targetPropertyName, if (targetProperty.objectReferenceValue != null) { var type = targetProperty.objectReferenceValue.GetType(); - EditorUtil.PropertyTreeMenu(propertyName, type, property); + GUIMenu.DrawPropertyMenu(null, targetProperty.objectReferenceValue.GetType(), propertyName, property); } } } diff --git a/Editor/Script/Util.meta b/Editor/Script/GUI.meta similarity index 77% rename from Editor/Script/Util.meta rename to Editor/Script/GUI.meta index f432a36..5e547b6 100644 --- a/Editor/Script/Util.meta +++ b/Editor/Script/GUI.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 996dea58e5e1c7a40aebe2f58c0ee62f +guid: fd2c0dd42a1bfea4cb47b919cd1c5384 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Editor/Script/GUI/EditorIcon.cs b/Editor/Script/GUI/EditorIcon.cs new file mode 100644 index 0000000..e0c1fe5 --- /dev/null +++ b/Editor/Script/GUI/EditorIcon.cs @@ -0,0 +1,66 @@ +#if UNITY_EDITOR +using System; +using UnityEditor; +using UnityEngine; + +namespace Aya.DataBinding +{ + public static class EditorIcon + { + #region Icon Method + + public static Texture2D CreateIcon(Type type, int size = 24) + { + var srcIcon = GetIcon(type); + if (srcIcon == null) return default; + var icon = CreateIconWithSrc(srcIcon, size); + return icon; + } + + public static Texture2D CreateIcon(string name, int size = 24) + { + var srcIcon = GetIcon(name); + if (srcIcon == null) return default; + var icon = CreateIconWithSrc(srcIcon, size); + return icon; + } + + public static Texture2D GetIcon(Type type) + { + if (type != null) return EditorGUIUtility.ObjectContent(null, type).image as Texture2D; + return default; + } + + public static Texture2D GetIcon(string name) + { + if (!string.IsNullOrEmpty(name)) + { + var icon = EditorGUIUtility.FindTexture(name); + if (icon == null) icon = AssetDatabase.GetCachedIcon(name) as Texture2D; + if (icon == null) icon = EditorGUIUtility.IconContent(name).image as Texture2D; + return icon; + } + + return default; + } + + public static Texture2D CreateIconWithSrc(Texture2D srcIcon, int size = 24) + { + // Copy Built-in texture with RenderTexture + var tempRenderTexture = RenderTexture.GetTemporary(size, size, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear); + Graphics.Blit(srcIcon, tempRenderTexture); + var previousRenderTexture = RenderTexture.active; + RenderTexture.active = tempRenderTexture; + var icon = new Texture2D(size, size); + icon.ReadPixels(new Rect(0, 0, tempRenderTexture.width, tempRenderTexture.height), 0, 0); + icon.Apply(); + RenderTexture.ReleaseTemporary(tempRenderTexture); + RenderTexture.active = previousRenderTexture; + return icon; + } + + #endregion + } + +} +#endif \ No newline at end of file diff --git a/Editor/Script/GUI/EditorIcon.cs.meta b/Editor/Script/GUI/EditorIcon.cs.meta new file mode 100644 index 0000000..793e432 --- /dev/null +++ b/Editor/Script/GUI/EditorIcon.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 94bb0413295c96c49860fc3db98e7d92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Script/Util/EditorStyle.cs b/Editor/Script/GUI/EditorStyle.cs similarity index 100% rename from Editor/Script/Util/EditorStyle.cs rename to Editor/Script/GUI/EditorStyle.cs diff --git a/Editor/Script/Util/EditorStyle.cs.meta b/Editor/Script/GUI/EditorStyle.cs.meta similarity index 100% rename from Editor/Script/Util/EditorStyle.cs.meta rename to Editor/Script/GUI/EditorStyle.cs.meta diff --git a/Editor/Script/GUI/GUIMenu.cs b/Editor/Script/GUI/GUIMenu.cs new file mode 100644 index 0000000..1126f84 --- /dev/null +++ b/Editor/Script/GUI/GUIMenu.cs @@ -0,0 +1,68 @@ +#if UNITY_EDITOR +using System; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace Aya.DataBinding +{ + public static partial class GUIMenu + { + public static void DrawSearchableDropdownMenu(string propertyName, + SearchableDropdown menu, + Func checkNullFunc, + Func currentDisplayNameGetter) + { + var isNull = checkNullFunc(); + using (GUIErrorColorArea.Create(isNull)) + { + GUILayout.BeginHorizontal(); + GUILayout.Label(propertyName, GUILayout.Width(EditorGUIUtility.labelWidth)); + + var displayName = currentDisplayNameGetter(); + var currentPropertyDisplayName = isNull ? EditorStyle.NoneStr : displayName; + var btnRect = GUILayoutUtility.GetRect(new GUIContent(currentPropertyDisplayName), EditorStyles.toolbarButton); + var btnType = GUI.Button(btnRect, currentPropertyDisplayName, EditorStyles.popup); + if (btnType) + { + btnRect.width = EditorGUIUtility.currentViewWidth; + menu.Show(btnRect, 500f); + } + + GUILayout.EndHorizontal(); + } + } + + public static SearchableDropdown CreateSearchableDropdownMenu(string menuTitle, + IEnumerable valueSource, + Func pathGetter, + Func iconGetter, + Action onClick = null) + { + var root = new SearchableDropdownItem(menuTitle); + var menu = new SearchableDropdown(root, item => + { + var value = (T)item.Value; + onClick?.Invoke(value); + }); + + root.AddChild(new SearchableDropdownItem(EditorStyle.NoneStr, null)); + root.AddSeparator(); + + foreach (var value in valueSource) + { + var path = pathGetter(value); + var icon = iconGetter(value); + var item = new SearchableDropdownItem(path, value) + { + icon = icon + }; + + root.AddChild(item); + } + + return menu; + } + } +} +#endif \ No newline at end of file diff --git a/Editor/Script/GUI/GUIMenu.cs.meta b/Editor/Script/GUI/GUIMenu.cs.meta new file mode 100644 index 0000000..1ce53c3 --- /dev/null +++ b/Editor/Script/GUI/GUIMenu.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 080cc72ba5b0f4f4cad89d46b29bb56f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Script/Util/GUIStruct.cs b/Editor/Script/GUI/GUIStruct.cs similarity index 91% rename from Editor/Script/Util/GUIStruct.cs rename to Editor/Script/GUI/GUIStruct.cs index a3c771e..4a3fba7 100644 --- a/Editor/Script/Util/GUIStruct.cs +++ b/Editor/Script/GUI/GUIStruct.cs @@ -200,5 +200,29 @@ public void Dispose() GUI.color = OriginalColor; } } + + public struct GUIErrorColorArea : IDisposable + { + public Color OriginalColor; + + public static GUIErrorColorArea Create(bool check = true) + { + return new GUIErrorColorArea(check); + } + + public GUIErrorColorArea(bool check = true) + { + OriginalColor = GUI.color; + if (check) + { + GUI.color = new Color(1f, 0.5f, 0.5f); + } + } + + public void Dispose() + { + GUI.color = OriginalColor; + } + } } #endif \ No newline at end of file diff --git a/Editor/Script/Util/GUIStruct.cs.meta b/Editor/Script/GUI/GUIStruct.cs.meta similarity index 100% rename from Editor/Script/Util/GUIStruct.cs.meta rename to Editor/Script/GUI/GUIStruct.cs.meta diff --git a/Editor/Script/Util/EditorUtil.cs b/Editor/Script/GUI/GUIUtil.cs similarity index 53% rename from Editor/Script/Util/EditorUtil.cs rename to Editor/Script/GUI/GUIUtil.cs index 200e1fb..a2021e8 100644 --- a/Editor/Script/Util/EditorUtil.cs +++ b/Editor/Script/GUI/GUIUtil.cs @@ -6,7 +6,7 @@ namespace Aya.DataBinding { - public static class EditorUtil + public static class GUIUtil { #region Assembly & Type @@ -99,167 +99,6 @@ void OnClick(SearchableDropdownItem item) #endregion - #region Components Tree Menu - - public static SearchableDropdownItem CreateComponentsTreeMenu(Transform parent) where TComponent : Component - { - var root = new SearchableDropdownItem(typeof(TComponent).Name); - root.AddChild(new SearchableDropdownItem(EditorStyle.NoneStr, null)); - root.AddSeparator(); - CreateComponentsTreeMenuRecursion(root, parent, ""); - return root; - } - - private static void CreateComponentsTreeMenuRecursion(SearchableDropdownItem root, Transform parent, string path) where TComponent : Component - { - var components = parent.GetComponents(); - for (var i = 0; i < components.Length; i++) - { - var component = components[i]; - var componentName = component.GetType().Name; - var child = new SearchableDropdownItem(path + componentName, component) - { - icon = EditorGUIUtility.ObjectContent(component, component.GetType()).image as Texture2D - }; - - root.AddChild(child); - } - - if (parent.childCount <= 0) return; - root.AddSeparator(); - for (var i = 0; i < parent.childCount; i++) - { - var childTrans = parent.GetChild(i); - CreateComponentsTreeMenuRecursion(root, childTrans, path + childTrans.name + " \\ "); - } - } - - public static void ComponentTreeMenu(string propertyName, SerializedProperty property, Transform parent, Action onClick = null) where TComponent : Component - { - var menu = CreateComponentsTreeMenu(parent); - void OnClick(SearchableDropdownItem item) - { - TComponent target = null; - if (item.Value == null) - { - property.objectReferenceValue = null; - } - else - { - target = item.Value as TComponent; - property.objectReferenceValue = target; - } - - property.serializedObject.ApplyModifiedProperties(); - onClick?.Invoke(target); - } - - SearchableComponentDropdownList(propertyName, property, menu, OnClick); - } - - public static void SearchableComponentDropdownList(string propertyName, SerializedProperty property, SearchableDropdownItem root, Action onClick = null) where TComponent : Component - { - using (new ColorScope(EditorStyle.ErrorColor, () => property.objectReferenceValue == null)) - { - GUILayout.BeginHorizontal(); - GUILayout.Label(propertyName, GUILayout.Width(EditorGUIUtility.labelWidth)); - property.objectReferenceValue = EditorGUILayout.ObjectField(property.objectReferenceValue, typeof(TComponent), true); - var btnRect = GUILayoutUtility.GetLastRect(); - var btnType = GUILayout.Button("▽", EditorStyles.popup, GUILayout.Width(EditorGUIUtility.singleLineHeight)); - if (btnType) - { - btnRect.width = EditorGUIUtility.currentViewWidth; - var dropdown = new SearchableDropdown(root, onClick); - dropdown.Show(btnRect, 300f); - } - - GUILayout.EndHorizontal(); - } - } - - #endregion - - #region Type Property Menu - - public static GenericMenu CreatePropertyMenu(Type type, SerializedProperty property, Action onClickProperty = null, Action onClickField = null) - { - var menu = new GenericMenu(); - menu.AddItem(new GUIContent(EditorStyle.NoneStr), string.IsNullOrEmpty(property.stringValue), () => - { - property.stringValue = ""; - property.serializedObject.ApplyModifiedProperties(); - }); - menu.AddSeparator(""); - - var propertyInfos = TypeCaches.GetTypeProperties(type); - var prefix = "Property/"; - for (var i = 0; i < propertyInfos.Count; i++) - { - var propertyInfo = propertyInfos[i]; - // if (!TypeCaches.BindableTypes.Contains(propertyInfo.PropertyType)) continue; - var displayName = propertyInfo.Name + "\t\t" + propertyInfo.PropertyType.Name; - menu.AddItem(new GUIContent(prefix + displayName), propertyInfo.Name == property.stringValue, () => - { - property.stringValue = propertyInfo.Name; - property.serializedObject.ApplyModifiedProperties(); - onClickProperty?.Invoke(propertyInfo); - }); - } - - var filedInfos = TypeCaches.GetTypeFields(type); - prefix = "Field/"; - for (var i = 0; i < filedInfos.Count; i++) - { - var fieldInfo = filedInfos[i]; - // if (!TypeCaches.BindableTypes.Contains(fieldInfo.FieldType)) continue; - var displayName = fieldInfo.Name + "\t\t" + fieldInfo.FieldType.Name; - menu.AddItem(new GUIContent(prefix + displayName), fieldInfo.Name == property.stringValue, () => - { - property.stringValue = fieldInfo.Name; - property.serializedObject.ApplyModifiedProperties(); - onClickField?.Invoke(fieldInfo); - }); - } - - return menu; - } - - public static void PropertyTreeMenu(string propertyName, Type type, SerializedProperty property, Action onClickProperty = null, Action onClickField = null) - { - var menu = CreatePropertyMenu(type, property, onClickProperty, onClickField); - bool CheckNullFunc() => !TypeCaches.CheckTypeHasPropertyOrFieldByName(type, property.stringValue); - void ResetFunc() => property.stringValue = null; - - (string currentPropertyName, string currentPropertyTypeName) GetCurrentPropertyInfo() - { - if (string.IsNullOrEmpty(property.stringValue)) return (EditorStyle.NoneStr, ""); - var (propertyInfo, filedInfo) = TypeCaches.GetTypePropertyOrFieldByName(type, property.stringValue); - if (propertyInfo != null) - { - return (propertyInfo.Name, propertyInfo.PropertyType.Name); - } - - return filedInfo != null ? (filedInfo.Name, filedInfo.FieldType.Name) : (EditorStyle.NoneStr, ""); - } - - var (currentPropertyName, currentPropertyTypeName) = GetCurrentPropertyInfo(); - - string CurrentDisplayNameGetter() - { - return currentPropertyName; - } - - if (!string.IsNullOrEmpty(currentPropertyTypeName)) - { - currentPropertyTypeName = " (" + currentPropertyTypeName + ")"; - } - - var displayPropertyName = propertyName + currentPropertyTypeName; - DropdownList(displayPropertyName, menu, CheckNullFunc, ResetFunc, CurrentDisplayNameGetter); - } - - #endregion - #region Dropdown public static void DropdownList(string propertyName, GenericMenu menu, Func checkNullFunc, Action resetFunc, Func currentDisplayNameGetter) @@ -374,6 +213,27 @@ public static int DrawToolbarEnum(int value, string propertyName, Type enumType) } #endregion + + #region Button + + public static bool DrawSearchMenuButton() + { + var button = DrawIconButton("Search Icon", "Search"); + return button; + } + + public static bool DrawIconButton(string iconName, string toolTip = "") + { + var content = new GUIContent(EditorGUIUtility.IconContent(iconName)) + { + tooltip = toolTip + }; + + var button = GUILayout.Button(content, EditorStyles.miniButtonMid, GUILayout.Width(EditorGUIUtility.singleLineHeight)); + return button; + } + + #endregion } } #endif \ No newline at end of file diff --git a/Editor/Script/Util/EditorUtil.cs.meta b/Editor/Script/GUI/GUIUtil.cs.meta similarity index 100% rename from Editor/Script/Util/EditorUtil.cs.meta rename to Editor/Script/GUI/GUIUtil.cs.meta diff --git a/Editor/Script/GUI/Menu.meta b/Editor/Script/GUI/Menu.meta new file mode 100644 index 0000000..96ab21e --- /dev/null +++ b/Editor/Script/GUI/Menu.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2eff4e4d76c81ce4891a0ed75165332b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Script/GUI/Menu/ComponentsTreeMenu.cs b/Editor/Script/GUI/Menu/ComponentsTreeMenu.cs new file mode 100644 index 0000000..2d94d82 --- /dev/null +++ b/Editor/Script/GUI/Menu/ComponentsTreeMenu.cs @@ -0,0 +1,118 @@ +#if UNITY_EDITOR +using System; +using UnityEditor; +using UnityEngine; + +namespace Aya.DataBinding +{ + public static partial class GUIMenu + { + public static SearchableDropdownItem CreateComponentsTreeMenu(Transform parent) where TComponent : Component + { + return CreateComponentsTreeMenu(typeof(TComponent), parent); + } + + public static SearchableDropdownItem CreateComponentsTreeMenu(Type componentType, Transform parent) + { + var root = new SearchableDropdownItem(componentType.Name); + root.AddChild(new SearchableDropdownItem(EditorStyle.NoneStr, null)); + root.AddSeparator(); + CreateComponentsTreeMenuRecursion(componentType, root, parent, ""); + return root; + } + + private static void CreateComponentsTreeMenuRecursion(SearchableDropdownItem root, Transform parent, string path) where TComponent : Component + { + CreateComponentsTreeMenuRecursion(typeof(TComponent), root, parent, path); + } + + private static void CreateComponentsTreeMenuRecursion(Type componentType, SearchableDropdownItem root, Transform parent, string path) + { + var components = parent.GetComponents(componentType); + foreach (var component in components) + { + var componentName = component.GetType().Name; + var child = new SearchableDropdownItem(path + componentName, component) + { + icon = EditorGUIUtility.ObjectContent(component, component.GetType()).image as Texture2D + }; + + root.AddChild(child); + } + + if (parent.childCount == 0) return; + if (components.Length > 0) + { + root.AddSeparator(); + } + + for (var i = 0; i < parent.childCount; i++) + { + var childTrans = parent.GetChild(i); + CreateComponentsTreeMenuRecursion(componentType, root, childTrans, path + childTrans.name + " \\ "); + } + } + + public static void ComponentTreeMenu(string propertyName, SerializedProperty property, Transform parent, Action onClick = null) where TComponent : Component + { + ComponentTreeMenu(typeof(TComponent), propertyName, property, parent, obj => + { + var target = (TComponent)obj; + onClick?.Invoke(target); + }); + } + + public static void ComponentTreeMenu(Type componentType, string propertyName, SerializedProperty property, Transform parent, Action onClick = null) + { + var menu = parent != null ? CreateComponentsTreeMenu(componentType, parent) : null; + + void OnClick(SearchableDropdownItem item) + { + UnityEngine.Object target = null; + if (item.Value == null) + { + property.objectReferenceValue = null; + } + else + { + target = (UnityEngine.Object)item.Value; + property.objectReferenceValue = target; + } + + property.serializedObject.ApplyModifiedProperties(); + onClick?.Invoke(target); + } + + SearchableComponentDropdownList(componentType, propertyName, property, menu, OnClick); + } + + public static void SearchableComponentDropdownList(string propertyName, SerializedProperty property, SearchableDropdownItem root, Action onClick = null) where TComponent : Component + { + SearchableComponentDropdownList(typeof(TComponent), propertyName, property, root, onClick); + } + + public static void SearchableComponentDropdownList(Type componentType, string propertyName, SerializedProperty property, SearchableDropdownItem root, Action onClick = null) + { + using (GUIErrorColorArea.Create(property.objectReferenceValue == null)) + { + using (GUIHorizontal.Create()) + { + GUILayout.Label(propertyName, EditorStyles.label, GUILayout.Width(EditorGUIUtility.labelWidth)); + property.objectReferenceValue = EditorGUILayout.ObjectField(property.objectReferenceValue, componentType, true); + + if (root != null) + { + var btnRect = GUILayoutUtility.GetLastRect(); + if (GUIUtil.DrawSearchMenuButton()) + { + btnRect.width = EditorGUIUtility.currentViewWidth; + var dropdown = new SearchableDropdown(root, onClick); + dropdown.Show(btnRect, 500f); + } + } + } + } + } + } +} +#endif \ No newline at end of file diff --git a/Editor/Script/GUI/Menu/ComponentsTreeMenu.cs.meta b/Editor/Script/GUI/Menu/ComponentsTreeMenu.cs.meta new file mode 100644 index 0000000..2fa209d --- /dev/null +++ b/Editor/Script/GUI/Menu/ComponentsTreeMenu.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0cdf5806265423742b0272e470488c16 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Script/GUI/Menu/PropertyMenu.cs b/Editor/Script/GUI/Menu/PropertyMenu.cs new file mode 100644 index 0000000..5c65f17 --- /dev/null +++ b/Editor/Script/GUI/Menu/PropertyMenu.cs @@ -0,0 +1,55 @@ +#if UNITY_EDITOR +using System; +using System.Collections.Generic; +using System.Reflection; +using UnityEditor; + +namespace Aya.DataBinding +{ + public static partial class GUIMenu + { + public static void DrawPropertyMenu(Type filterPropertyType, Type targetType, string propertyName, SerializedProperty property) + { + var menu = CreateSearchableDropdownMenu(nameof(MemberTypes.Property), + GetTargetPropertyList(filterPropertyType, targetType), + memberInfo => + { + var displayName = memberInfo.MemberType + " / " + memberInfo.Name; + return displayName; + }, + memberInfo => EditorIcon.GetIcon("ScriptableObject Icon"), + memberInfo => + { + property.stringValue = memberInfo == null ? "" : memberInfo.Name; + property.serializedObject.ApplyModifiedProperties(); + }); + + DrawSearchableDropdownMenu(propertyName, + menu, + () => string.IsNullOrEmpty(property.stringValue), + () => property.stringValue); + } + + public static List GetTargetPropertyList(Type filterPropertyType, Type targetType) + { + var result = new List(); + var flags = TypeCaches.DefaultBindingFlags; + var properties = targetType.GetProperties(flags); + foreach (var propertyInfo in properties) + { + if (filterPropertyType != null && propertyInfo.PropertyType != filterPropertyType) continue; + result.Add(propertyInfo); + } + + var fields = targetType.GetFields(flags); + foreach (var fieldInfo in fields) + { + if (filterPropertyType != null && fieldInfo.FieldType != filterPropertyType) continue; + result.Add(fieldInfo); + } + + return result; + } + } +} +#endif \ No newline at end of file diff --git a/Editor/Script/GUI/Menu/PropertyMenu.cs.meta b/Editor/Script/GUI/Menu/PropertyMenu.cs.meta new file mode 100644 index 0000000..b72a5aa --- /dev/null +++ b/Editor/Script/GUI/Menu/PropertyMenu.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 307641d9152cc7d429653285102eb148 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Script/GUI/SearchableDropdown.meta b/Editor/Script/GUI/SearchableDropdown.meta new file mode 100644 index 0000000..2122dd0 --- /dev/null +++ b/Editor/Script/GUI/SearchableDropdown.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0b1e7d282d5e37a4a8dc5eceeeefaf4c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Script/SearchableDropdown.cs b/Editor/Script/GUI/SearchableDropdown/AdvancedDropdownExtensions.cs similarity index 60% rename from Editor/Script/SearchableDropdown.cs rename to Editor/Script/GUI/SearchableDropdown/AdvancedDropdownExtensions.cs index a0f57b1..55b7bf5 100644 --- a/Editor/Script/SearchableDropdown.cs +++ b/Editor/Script/GUI/SearchableDropdown/AdvancedDropdownExtensions.cs @@ -1,43 +1,10 @@ -#if UNITY_EDITOR -using System; +#if UNITY_EDITOR using UnityEditor; using UnityEditor.IMGUI.Controls; using UnityEngine; namespace Aya.DataBinding { - public class SearchableDropdownItem : AdvancedDropdownItem - { - public object Value; - - public SearchableDropdownItem(string name, object value = null) : base(name) - { - Value = value; - } - } - - public class SearchableDropdown : AdvancedDropdown - { - public SearchableDropdownItem Root; - public Action OnSelected; - - public SearchableDropdown(SearchableDropdownItem root, Action onSelected = null) : base(new AdvancedDropdownState()) - { - Root = root; - OnSelected = onSelected; - } - - protected override AdvancedDropdownItem BuildRoot() - { - return Root; - } - - protected override void ItemSelected(AdvancedDropdownItem item) - { - OnSelected?.Invoke(item as SearchableDropdownItem); - } - } - public static class AdvancedDropdownExtensions { public static void Show(this AdvancedDropdown dropdown, Rect buttonRect, float maxHeight) @@ -75,6 +42,5 @@ private static void SetMaxHeightForOpenedPopup(Rect buttonRect, float maxHeight) window.ShowAsDropDown(GUIUtility.GUIToScreenRect(buttonRect), position.size); } } - } #endif \ No newline at end of file diff --git a/Editor/Script/GUI/SearchableDropdown/AdvancedDropdownExtensions.cs.meta b/Editor/Script/GUI/SearchableDropdown/AdvancedDropdownExtensions.cs.meta new file mode 100644 index 0000000..88989c8 --- /dev/null +++ b/Editor/Script/GUI/SearchableDropdown/AdvancedDropdownExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3e61159ea6c7c5e4bbd4283553156c40 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Script/GUI/SearchableDropdown/SearchableDropdown.cs b/Editor/Script/GUI/SearchableDropdown/SearchableDropdown.cs new file mode 100644 index 0000000..97d45ee --- /dev/null +++ b/Editor/Script/GUI/SearchableDropdown/SearchableDropdown.cs @@ -0,0 +1,29 @@ +#if UNITY_EDITOR +using System; +using UnityEditor.IMGUI.Controls; + +namespace Aya.DataBinding +{ + public class SearchableDropdown : AdvancedDropdown + { + public SearchableDropdownItem Root; + public Action OnSelected; + + public SearchableDropdown(SearchableDropdownItem root, Action onSelected = null) : base(new AdvancedDropdownState()) + { + Root = root; + OnSelected = onSelected; + } + + protected override AdvancedDropdownItem BuildRoot() + { + return Root; + } + + protected override void ItemSelected(AdvancedDropdownItem item) + { + OnSelected?.Invoke(item as SearchableDropdownItem); + } + } +} +#endif \ No newline at end of file diff --git a/Editor/Script/SearchableDropdown.cs.meta b/Editor/Script/GUI/SearchableDropdown/SearchableDropdown.cs.meta similarity index 83% rename from Editor/Script/SearchableDropdown.cs.meta rename to Editor/Script/GUI/SearchableDropdown/SearchableDropdown.cs.meta index 6e4c160..fe775bc 100644 --- a/Editor/Script/SearchableDropdown.cs.meta +++ b/Editor/Script/GUI/SearchableDropdown/SearchableDropdown.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6504c86981f0adc4ebb36e7eda799fc0 +guid: 6321f133a3740b74d900b35475712b77 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Editor/Script/GUI/SearchableDropdown/SearchableDropdownItem.cs b/Editor/Script/GUI/SearchableDropdown/SearchableDropdownItem.cs new file mode 100644 index 0000000..7056611 --- /dev/null +++ b/Editor/Script/GUI/SearchableDropdown/SearchableDropdownItem.cs @@ -0,0 +1,16 @@ +#if UNITY_EDITOR +using UnityEditor.IMGUI.Controls; + +namespace Aya.DataBinding +{ + public class SearchableDropdownItem : AdvancedDropdownItem + { + public object Value; + + public SearchableDropdownItem(string name, object value = null) : base(name) + { + Value = value; + } + } +} +#endif \ No newline at end of file diff --git a/Editor/Script/GUI/SearchableDropdown/SearchableDropdownItem.cs.meta b/Editor/Script/GUI/SearchableDropdown/SearchableDropdownItem.cs.meta new file mode 100644 index 0000000..d40e569 --- /dev/null +++ b/Editor/Script/GUI/SearchableDropdown/SearchableDropdownItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02712715e497efd4f80efd1646e7786f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Script/PropertyBinderEditor.cs b/Editor/Script/PropertyBinderEditor.cs index 23c2961..a01f890 100644 --- a/Editor/Script/PropertyBinderEditor.cs +++ b/Editor/Script/PropertyBinderEditor.cs @@ -26,7 +26,7 @@ public override void DrawBody() } var type = PropertyBinder.Target.GetType(); - EditorUtil.PropertyTreeMenu("Dst Property", type, PropertyNameProperty); + GUIMenu.DrawPropertyMenu(null, PropertyBinder.Target.GetType(), "Property", PropertyNameProperty); } } } diff --git a/Editor/Script/TypeBinderEditor.cs b/Editor/Script/TypeBinderEditor.cs index 6aa505f..ac160cd 100644 --- a/Editor/Script/TypeBinderEditor.cs +++ b/Editor/Script/TypeBinderEditor.cs @@ -39,8 +39,8 @@ public override void OnInspectorGUI() DrawDataKey(DataKeyProperty); DrawDirection(DirectionProperty); - EditorUtil.AssemblyMenu("Assembly", AssemblyProperty); - EditorUtil.TypeMenu("Type", TypeProperty, AssemblyProperty.stringValue); + GUIUtil.AssemblyMenu("Assembly", AssemblyProperty); + GUIUtil.TypeMenu("Type", TypeProperty, AssemblyProperty.stringValue); var currentType = TypeCaches.GetTypeByName(AssemblyProperty.stringValue, TypeProperty.stringValue); if (currentType != null) @@ -78,7 +78,7 @@ protected virtual void DrawTypeMapList(Type currentType) var componentProperty = itemProperty.FindPropertyRelative("Target"); var targetPropertyProperty = itemProperty.FindPropertyRelative("TargetProperty"); - EditorUtil.PropertyTreeMenu("Source Prop", currentType, propertyProperty); + GUIMenu.DrawPropertyMenu(null, currentType, "Source Prop", propertyProperty); DrawTargetAndProperty("Target", componentProperty, TypeBinder.transform, "Target Prop", targetPropertyProperty); } @@ -90,7 +90,7 @@ protected virtual void DrawTypeMapList(Type currentType) } } - EditorUtil.ColorLine(EditorStyle.SplitLineColor, 2); + GUIUtil.ColorLine(EditorStyle.SplitLineColor, 2); } if (GUILayout.Button("+")) diff --git a/Samples/Sample_02_TypeBinder/Scene/UBind_Sample_02_TypeBInder.unity b/Samples/Sample_02_TypeBinder/Scene/UBind_Sample_02_TypeBInder.unity index 9c13f78..4c8becf 100644 --- a/Samples/Sample_02_TypeBinder/Scene/UBind_Sample_02_TypeBInder.unity +++ b/Samples/Sample_02_TypeBinder/Scene/UBind_Sample_02_TypeBInder.unity @@ -38,12 +38,12 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_IndirectSpecularColor: {r: 0.44402242, g: 0.49316543, b: 0.5722324, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &3 LightmapSettings: m_ObjectHideFlags: 0 - serializedVersion: 11 + serializedVersion: 12 m_GIWorkflowMode: 1 m_GISettings: serializedVersion: 2 @@ -98,7 +98,7 @@ LightmapSettings: m_TrainingDataDestination: TrainingData m_LightProbeSampleCountMultiplier: 4 m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 + m_LightingSettings: {fileID: 0} --- !u!196 &4 NavMeshSettings: serializedVersion: 2 @@ -118,6 +118,8 @@ NavMeshSettings: manualTileSize: 0 tileSize: 256 accuratePlacement: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 debug: m_Flags: 0 m_NavMeshData: {fileID: 0} @@ -147,6 +149,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1964096077} m_Father: {fileID: 757761686} @@ -183,6 +186,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1809763290} m_Father: {fileID: 757761686} @@ -221,6 +225,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1965111894} m_RootOrder: 1 @@ -245,6 +250,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -300,6 +306,11 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: ab5d0a64497764e49a8b9fa974475dd3, type: 3} m_Name: m_EditorClassIdentifier: + Player: + Name: + Exp: 0 + Stat: 0 + PlayTime: 0 --- !u!4 &678997529 Transform: m_ObjectHideFlags: 0 @@ -310,6 +321,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 4 @@ -341,6 +353,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 2032077265} - {fileID: 134559210} @@ -367,6 +380,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_Navigation: m_Mode: 3 + m_WrapAround: 0 m_SelectOnUp: {fileID: 0} m_SelectOnDown: {fileID: 0} m_SelectOnLeft: {fileID: 0} @@ -431,6 +445,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1965111894} m_RootOrder: 3 @@ -455,6 +470,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -557,6 +573,7 @@ Light: m_UseColorTemperature: 0 m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 m_ShadowRadius: 0 m_ShadowAngle: 0 --- !u!4 &937966826 @@ -569,6 +586,7 @@ Transform: m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} m_LocalPosition: {x: 0, y: 3, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 1 @@ -631,6 +649,7 @@ MonoBehaviour: m_FallbackScreenDPI: 96 m_DefaultSpriteDPI: 96 m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 --- !u!223 &1155611983 Canvas: m_ObjectHideFlags: 0 @@ -662,6 +681,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1965111894} m_Father: {fileID: 0} @@ -751,6 +771,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 1, z: -10} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 @@ -784,28 +805,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: efa53029e0a62304caf81173265515b9, type: 3} m_Name: m_EditorClassIdentifier: - undoProRecords: [] - undoState: - redoRecords: [] - undoRecords: - - Selection Change - - Selection Change - - Selection Change - - Inspector - - Selection Change - - Selection Change - - Inspector - - Inspector - - Inspector - - Inspector - - Inspector - - Inspector - - Inspector - - Inspector - - Inspector - - Selection Change - - Selection Change - - Selection Change --- !u!4 &1728913405 Transform: m_ObjectHideFlags: 3 @@ -816,6 +815,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 5 @@ -850,6 +850,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} m_Name: m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 m_HorizontalAxis: Horizontal m_VerticalAxis: Vertical m_SubmitButton: Submit @@ -882,6 +883,7 @@ Transform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 3 @@ -914,6 +916,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 171881611} m_RootOrder: 0 @@ -938,6 +941,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -988,6 +992,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1965111894} m_RootOrder: 0 @@ -1012,6 +1017,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -1066,6 +1072,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 134559210} m_RootOrder: 0 @@ -1090,6 +1097,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: @@ -1139,6 +1147,7 @@ RectTransform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 1916309533} - {fileID: 226262415} @@ -1164,7 +1173,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 51de3718b79a0744ca6cf58442638eb9, type: 3} m_Name: m_EditorClassIdentifier: - Context: Default + Container: Default Key: PlayerData Direction: 1 Assembly: Aya.DataBinding @@ -1210,6 +1219,7 @@ RectTransform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 757761686} m_RootOrder: 0 @@ -1234,6 +1244,7 @@ MonoBehaviour: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: