Last active
July 24, 2024 10:03
-
-
Save SolarianZ/d7572ff6047dccabe58f861022fb0b53 to your computer and use it in GitHub Desktop.
{"category": "Unity Engine/Editor/Extensions", "keywords": "Unity, Editor, UI, Odin, Foldout, Collapse, List, Element"} Odin extension for foldout elements in list.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Odin extension for foldout elements in list. | |
| // Example: | |
| // [Serializable] | |
| // public class MyData1 : IFoldoutableInList | |
| // { | |
| // // members... | |
| // } | |
| // [Serializable] | |
| // public class MyData2 : IForceFoldoutableInList | |
| // { | |
| // // members... | |
| // } | |
| // public class Test : MonoBehaviour | |
| // { | |
| // [ElementFoldoutable] | |
| // public List<MyData1> dataList1 = new List<MyData1>(); | |
| // public List<MyData2> dataList2 = new List<MyData2>(); | |
| // } | |
| using System; | |
| using System.Collections; | |
| using System.Diagnostics; | |
| using Sirenix.OdinInspector.Editor; | |
| using UnityEditor; | |
| using UnityEngine; | |
| // Put the following classes to the Runtime folder | |
| public interface IFoldoutableInList { } // Work with ElementFoldoutableAttribute | |
| public interface IForceFoldoutableInList : IFoldoutableInList { } // No need to use ElementFoldoutableAttribute | |
| [Conditional("UNITY_EDITOR")] | |
| public class ElementFoldoutableAttribute : Attribute { } // Work with IFoldoutableInList | |
| // Put the following class to the Editor folder | |
| public class FoldoutableListElementDrawer : OdinValueDrawer<IFoldoutableInList> // use OdinValueDrawer<object> for all types | |
| { | |
| protected override void DrawPropertyLayout(GUIContent label) | |
| { | |
| if (!(Property.Parent.ValueEntry.WeakSmartValue is IList)) | |
| { | |
| CallNextDrawer(label); | |
| return; | |
| } | |
| string propertyLabel = null; | |
| foreach (InspectorProperty child in Property.Children) | |
| { | |
| if (child.Info.TypeOfValue == typeof(string)) | |
| { | |
| string childValue = child.ValueEntry.WeakSmartValue?.ToString(); | |
| if (!string.IsNullOrEmpty(childValue)) | |
| { | |
| propertyLabel = childValue; | |
| } | |
| break; | |
| } | |
| } | |
| propertyLabel ??= $"Element {Property.Index}"; | |
| Property.State.Expanded = EditorGUILayout.Foldout(Property.State.Expanded, propertyLabel); | |
| if (!Property.State.Expanded) | |
| { | |
| return; | |
| } | |
| using (new EditorGUI.IndentLevelScope()) | |
| { | |
| CallNextDrawer(label); | |
| } | |
| } | |
| protected override bool CanDrawValueProperty(InspectorProperty property) | |
| { | |
| if (typeof(IForceFoldoutableInList).IsAssignableFrom(property.Info.TypeOfValue)) | |
| { | |
| return true && base.CanDrawValueProperty(property); | |
| } | |
| foreach (Attribute attribute in property.Attributes) | |
| { | |
| if (attribute is ElementFoldoutableAttribute) | |
| { | |
| return true && base.CanDrawValueProperty(property); | |
| } | |
| } | |
| return false; | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There is a simpler way to achieve foldoutable list elements:
Sirenix.OdinInspector.ListDrawerSettingsAttributeto the list and assign values to theShowIndexLabelandListElementLabelNameparameters.ListElementLabelNameparameter (in this example, the name is "_comment").