Skip to content

Commit

Permalink
Rewamp of UnityEvent inspector!
Browse files Browse the repository at this point in the history
  • Loading branch information
Deadcows committed Jan 16, 2020
1 parent e855b7a commit 077c920
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 56 deletions.
2 changes: 0 additions & 2 deletions Attributes/RequireLayerOtRagAttributeHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#if UNITY_EDITOR
using Plugins.MyBox.Tools;

namespace MyBox.Internal
{
using UnityEditor;
Expand Down
173 changes: 173 additions & 0 deletions Tools/Features/CollapsableEventDrawer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// ----------------------------------------------------------------------------
// Author: ByronMayne
// https://gist.github.com/ByronMayne/70a46e73f3af7fb9fec7437174dd4858
// https://gist.github.com/ByronMayne
// https://github.com/ByronMayne
// ----------------------------------------------------------------------------

#if UNITY_EDITOR
namespace MyBox.Internal
{
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Events;

[CustomPropertyDrawer(typeof(UnityEvent))]
public class CollapsableEventDrawer : UnityEventDrawer
{
private class Styles
{
public readonly GUIStyle preButton = "RL FooterButton";
public GUIContent iconToolbarPlus = EditorGUIUtility.IconContent("Toolbar Plus", "|Add to list");
}

private const string CALLS_PROPERTY_PATH = "m_PersistentCalls.m_Calls";
private const string GET_STATE_METHOD_NAME = "GetState";
private const string REORDERABLE_LIST_FIELD_NAME = "m_ReorderableList";
private const float BUTTON_WIDTH = 30;
private const float BUTTON_SPACING = 30;
private static readonly BindingFlags NON_PULIC_INSTANCE_FLAGS = BindingFlags.NonPublic | BindingFlags.Instance;


// Points the field inside Sate which has the reorderable list.
private static FieldInfo _stateReorderableListFieldInfo;

// Points to the GetState method defined in UnityEventDrawer.
private static MethodInfo _getStateMethod;

// Cached array for using reflection
private static object[] _getStateArgs = new object[1];

// A class that contains all the custom styling we need
private static Styles _styles;


// True if we have persistent calls and false if we don't.
private bool _hasPersistentCalls;

// Holds all our reorderable lists that belong to our state
private IDictionary<State, ReorderableList> _lists;


/// <summary>
/// Used to initialize our values.
/// </summary>
public CollapsableEventDrawer()
{
_lists = new Dictionary<State, ReorderableList>();
}


/// <summary>
/// A wrapper around the GetState function that is private in <see cref="UnityEventDrawer"/>
/// </summary>
private State GetState(SerializedProperty property)
{
if (_getStateMethod == null)
{
_getStateMethod = typeof(UnityEventDrawer).GetMethod(GET_STATE_METHOD_NAME, NON_PULIC_INSTANCE_FLAGS);
}

_getStateArgs[0] = property;
return (State) _getStateMethod.Invoke(this, _getStateArgs);
}

/// <summary>
/// Tries to get the cached ReorderableList from the state.
/// </summary>
private ReorderableList GetList(SerializedProperty property)
{
State state = GetState(property);
if (_lists.ContainsKey(state))
{
return _lists[state];
}

ReorderableList list = GetReorderableListFromState(state);
list.draggable = true;
_lists[state] = list;
return list;
}


/// <summary>
/// Returns back the number of calls that are currently in the Unity Event.
/// </summary>
private bool HasPersistentCalls(SerializedProperty property)
{
return property.FindPropertyRelative(CALLS_PROPERTY_PATH).arraySize > 0;
}

/// <summary>
/// Returns to Unity to tell it how much space we should use to draw. If we
/// have one element we only reserve 32 units. 16 for the element itself and
/// 16 for spacing from the next element. If we any calls we let Unity
/// draw the default.
/// </summary>
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
_hasPersistentCalls = HasPersistentCalls(property);

ReorderableList list = GetList(property);

if (!_hasPersistentCalls)
{
list.elementHeight = 0;
list.displayAdd = false;
list.displayRemove = false;
return EditorGUIUtility.singleLineHeight * 2f;
}

list.elementHeight = 43;
list.displayAdd = true;
list.displayRemove = true;
return base.GetPropertyHeight(property, label);
}

/// <summary>
/// Used to draw our element override a bit of the Unity logic in the case
/// of having no elements.
/// </summary>
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (_styles == null)
{
_styles = new Styles();
}

base.OnGUI(position, property, label);

if (!_hasPersistentCalls)
{
position.x += position.width - BUTTON_SPACING;
position.width = BUTTON_WIDTH;
if (GUI.Button(position, _styles.iconToolbarPlus, _styles.preButton))
{
State state = GetState(property);
ReorderableList list = GetReorderableListFromState(state);
list.onAddCallback(list);
state.lastSelectedIndex = 0;
}
}
}


/// <summary>
/// Gets the internal instance of the <see cref="ReorderableList"/> that exists
/// in the state.
/// </summary>
private static ReorderableList GetReorderableListFromState(State state)
{
if (_stateReorderableListFieldInfo == null)
{
_stateReorderableListFieldInfo = typeof(State).GetField(REORDERABLE_LIST_FIELD_NAME, NON_PULIC_INSTANCE_FLAGS);
}

return (ReorderableList) _stateReorderableListFieldInfo.GetValue(state);
}
}
}
#endif
3 changes: 3 additions & 0 deletions Tools/Features/CollapsableEventDrawer.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 0 additions & 51 deletions Tools/OnPlaymodeLogger.cs

This file was deleted.

3 changes: 0 additions & 3 deletions Tools/OnPlaymodeLogger.cs.meta

This file was deleted.

0 comments on commit 077c920

Please sign in to comment.