Have you made any useful utilities with Odin?
Login and submit your creations hereThis drawer brings back prefab value override drawing features from default Unity drawing - every overriden value and all their parent classes have bolded label and blue line next to it.
Works with Odin 2.1.x and 3.x
May reduce editor's performance, if you have many, big classes nested into other classes, because script have to go throguh every child value trying to find overrides every time it is redrawn.
Gist version is easier and faster to modify, so use it as it may have newer version than here
PrefabOverrideDrawer.cs - just put it in Editor folder
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities;
using Sirenix.Utilities.Editor;
using UnityEditor;
using UnityEngine;
[DrawerPriority(0,10000,0)]
public sealed class PrefabOverrideDrawer<T> : OdinValueDrawer<T>
{
private static readonly Color OVERRIDE_MARGIN_COLOR = new Color(0.003921569f, 0.6f, 0.9215686f, 0.75f);
protected override bool CanDrawValueProperty(InspectorProperty property)
{
#if ODIN_INSPECTOR_3
return !property.IsTreeRoot && property.SupportsPrefabModifications && property.State.Enabled &&
property.State.Visible && property.Tree.PrefabModificationHandler.HasPrefabs &&
GlobalConfig<GeneralDrawerConfig>.Instance.ShowPrefabModifiedValueBar;
#else
return base.CanDrawValueProperty(property) && property.SupportsPrefabModifications &&
property.Tree.PrefabModificationHandler.HasPrefabs;
#endif
}
/// <summary>
/// Draws the property.
/// </summary>
protected override void DrawPropertyLayout(GUIContent label)
{
bool draw = Event.current.type == EventType.Repaint;
bool overriden = false;
bool childOrCollectionOverriden = false;
if (draw)
{
var valueOverriden = Property.ValueEntry != null && Property.ValueEntry.ValueChangedFromPrefab;
var childValueOverriden = false;
var collectionChanged = false;
if (!valueOverriden)
{
collectionChanged = Property.ValueEntry != null && (Property.ValueEntry.ListLengthChangedFromPrefab ||
Property.ValueEntry.DictionaryChangedFromPrefab);
if (!collectionChanged)
childValueOverriden = ChildValueOverriden(Property);
}
overriden = childOrCollectionOverriden = childValueOverriden || collectionChanged;
#if !ODIN_INSPECTOR_3
overriden = overriden || valueOverriden;
#endif
if (overriden)
GUIHelper.BeginLayoutMeasuring();
}
if (draw && childOrCollectionOverriden)
GUIHelper.PushIsBoldLabel(true);
CallNextDrawer(label);
if (draw && childOrCollectionOverriden)
GUIHelper.PopIsBoldLabel();
if (!draw || !overriden)
return;
var rect = GUIHelper.EndLayoutMeasuring();
var partOfCollection = Property.Parent != null && Property.Parent.ChildResolver is ICollectionResolver;
if (partOfCollection)
rect = GUIHelper.GetCurrentLayoutRect();
GUIHelper.IndentRect(ref rect);
GUIHelper.PushGUIEnabled(true);
if (!partOfCollection && childOrCollectionOverriden)
rect.height = EditorGUIUtility.singleLineHeight;
rect.width = 2;
rect.x -= 2;
SirenixEditorGUI.DrawSolidRect(rect, OVERRIDE_MARGIN_COLOR);
GUIHelper.PopGUIEnabled();
}
private static bool ChildValueOverriden(InspectorProperty property)
{
var children = property.Children;
var count = children.Count;
for (var index = 0; index < count; index++)
{
var child = children[index];
var valueEntry = child.ValueEntry;
if (valueEntry != null && (valueEntry.ValueChangedFromPrefab ||
valueEntry.ListLengthChangedFromPrefab ||
valueEntry.DictionaryChangedFromPrefab))
{
return true;
}
if (ChildValueOverriden(child))
return true;
}
return false;
}
}