Have you made any useful utilities with Odin?
Login and submit your creations hereAn attribute that makes big editors with a lot of data more easy to navigate.
The root/first PageSlider property will act as the slide container, and all PageSliders inside of that will be drawn as a buttons which will slide to that object when pressed.
Usage
[PageSlider]
public SomeTestClass test;
// Or place it above the class to enable it globally.
[PageSlider]
public class SomeOtherTestClass
{
}
SomeScriptableObject.cs Some random data for you to try it out with.
//
// Test data - you can delete this part or name the file SomeScriptableObject.cs and try it out
//
[CreateAssetMenu]
public class SomeScriptableObject : SerializedScriptableObject
{
[ShowInInspector]
[LabelText("$testName")]
public static SomeData test = new SomeData();
public string testName()
{
return test.Name;
}
}
[PageSlider, HideReferenceObjectPicker]
public class SomeData
{
public string Name;
public int b, c, d;
public SomeData b1, c1, d2;
[ListDrawerSettings(Expanded = true)]
public SomeData[] a = new SomeData[3];
[ListDrawerSettings(Expanded = true), InlineEditor(ObjectFieldMode = InlineEditorObjectFieldModes.Foldout, Expanded = true)]
[PageSlider]
public Material[] e = new Material[0];
public int f, g, h;
public override string ToString()
{
return this.Name ?? "Some Data";
}
}
PageSliderAttribute.cs
public class PageSliderAttribute : System.Attribute
{
}
PageSliderAttributeDrawer.cs
[DrawerPriority(0, 200, 0)]
public class PageSliderAttributeDrawer : OdinAttributeDrawer<PageSliderAttribute>
{
private static GUIStyle titleStyle;
private static SlidePageNavigationHelper<InspectorProperty> currentSlider;
private static InspectorProperty currentDrawingPageProperty;
private SlidePageNavigationHelper<InspectorProperty> slider;
private SlidePageNavigationHelper<InspectorProperty>.Page page;
private GUIContent pageLabel;
protected override bool CanDrawAttributeProperty(InspectorProperty property)
{
return !(property.ChildResolver is ICollectionResolver);
}
protected override void Initialize()
{
titleStyle = titleStyle ?? new GUIStyle("ShurikenModuleTitle");
}
protected override void DrawPropertyLayout(GUIContent label)
{
if (this.Property.ValueEntry.WeakSmartValue == null)
{
this.CallNextDrawer(label);
return;
}
this.UpdateBreadcrumbLabel(label);
if (currentSlider == null)
{
this.DrawPageSlider(label);
}
else if (currentDrawingPageProperty == this.Property)
{
this.CallNextDrawer(null);
}
else
{
if (GUILayout.Button(new GUIContent(this.GetLabelText(label)), titleStyle))
{
currentSlider.PushPage(this.Property, Guid.NewGuid().ToString());
currentSlider.EnumeratePages.Last();
this.page = currentSlider.EnumeratePages.Last();
this.page.Name = this.GetLabelText(label);
this.pageLabel = label;
}
}
}
private void UpdateBreadcrumbLabel(GUIContent label)
{
if (Event.current.type != EventType.Layout) return;
if (this.page == null) return;
if (this.pageLabel != null && this.pageLabel != this.Property.Label) return;
var newLabel = this.GetLabelText(label ?? this.pageLabel);
if (newLabel != this.page.Name)
{
this.page.Name = newLabel;
this.page.GetType().GetField("TitleWidth", Flags.AllMembers).SetValue(this.page, null);
}
}
private void DrawPageSlider(GUIContent label)
{
try
{
if (this.slider == null)
{
this.slider = new SlidePageNavigationHelper<InspectorProperty>();
this.slider.PushPage(this.Property, Guid.NewGuid().ToString());
this.page = this.slider.EnumeratePages.Last();
this.page.Name = this.GetLabelText(label);
}
currentSlider = this.slider;
SirenixEditorGUI.BeginBox();
SirenixEditorGUI.BeginToolbarBoxHeader();
{
var rect = GUILayoutUtility.GetRect(0, 20);
rect.x -= 5;
this.slider.DrawPageNavigation(rect);
}
SirenixEditorGUI.EndToolbarBoxHeader();
{
this.slider.BeginGroup();
foreach (var p in this.slider.EnumeratePages)
{
if (p.BeginPage())
{
if (p.Value == this.Property)
{
this.CallNextDrawer(null);
}
else
{
currentDrawingPageProperty = p.Value;
if (p.Value.Tree != this.Property.Tree)
{
InspectorUtilities.BeginDrawPropertyTree(p.Value.Tree, true);
}
p.Value.Draw(null);
if (p.Value.Tree != this.Property.Tree)
{
InspectorUtilities.EndDrawPropertyTree(p.Value.Tree);
}
currentDrawingPageProperty = null;
}
}
p.EndPage();
}
this.slider.EndGroup();
}
SirenixEditorGUI.EndBox();
}
finally
{
currentSlider = null;
}
}
private string GetLabelText(GUIContent label)
{
if (label != null)
{
return label.text;
}
var val = this.Property.ValueEntry.WeakSmartValue;
if (val == null)
{
return "Null";
}
var uObj = val as UnityEngine.Object;
if (uObj)
{
if (string.IsNullOrEmpty(uObj.name))
{
return uObj.ToString();
}
else
{
return uObj.name;
}
}
return val.ToString();
}
}