You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.7 KiB
C#
106 lines
3.7 KiB
C#
3 months ago
|
// Animancer // Copyright 2020 Kybernetik //
|
||
|
|
||
|
#if UNITY_EDITOR
|
||
|
|
||
|
#pragma warning disable CS0169 // Field is never used.
|
||
|
|
||
|
using UnityEditor;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.Events;
|
||
|
|
||
|
namespace Animancer.Editor
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// An object that holds a serialized callback (a <see cref="UnityEvent"/> by default) so that empty ones can be
|
||
|
/// drawn in the GUI without allocating array space for them until they actually contain something.
|
||
|
/// </summary>
|
||
|
internal sealed class DummySerializableCallback : ScriptableObject
|
||
|
{
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
[SerializeField] private SerializableCallbackHolder _Holder;
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
private static SerializedProperty _CallbackProperty;
|
||
|
|
||
|
private static SerializedProperty CallbackProperty
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
if (_CallbackProperty == null)
|
||
|
{
|
||
|
var instance = CreateInstance<DummySerializableCallback>();
|
||
|
|
||
|
instance.hideFlags = HideFlags.HideInHierarchy | HideFlags.DontSave;
|
||
|
var serializedObject = new SerializedObject(instance);
|
||
|
_CallbackProperty = serializedObject.FindProperty("_Holder._Callback");
|
||
|
|
||
|
AssemblyReloadEvents.beforeAssemblyReload += () =>
|
||
|
{
|
||
|
serializedObject.Dispose();
|
||
|
DestroyImmediate(instance);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
return _CallbackProperty;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
public static float Height
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return EditorGUI.GetPropertyHeight(CallbackProperty);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
public static bool DoCallbackGUI(ref Rect area, GUIContent label, SerializedProperty property,
|
||
|
out object callback)
|
||
|
{
|
||
|
var callbackProperty = CallbackProperty;
|
||
|
callbackProperty.serializedObject.Update();
|
||
|
callbackProperty.prefabOverride = property.prefabOverride;
|
||
|
|
||
|
area.height = Height;
|
||
|
|
||
|
EditorGUI.BeginChangeCheck();
|
||
|
label = EditorGUI.BeginProperty(area, label, property);
|
||
|
|
||
|
// UnityEvents ignore the proper indentation which makes them look terrible in a list.
|
||
|
// So we force the area to be indented.
|
||
|
var indentedArea = EditorGUI.IndentedRect(area);
|
||
|
var indentLevel = EditorGUI.indentLevel;
|
||
|
EditorGUI.indentLevel = 0;
|
||
|
|
||
|
EditorGUI.PropertyField(indentedArea, callbackProperty, label, false);
|
||
|
|
||
|
EditorGUI.indentLevel = indentLevel;
|
||
|
|
||
|
EditorGUI.EndProperty();
|
||
|
if (EditorGUI.EndChangeCheck())
|
||
|
{
|
||
|
callbackProperty.serializedObject.ApplyModifiedProperties();
|
||
|
callback = callbackProperty.GetValue();
|
||
|
|
||
|
callbackProperty.SetValue(null);
|
||
|
callbackProperty.serializedObject.Update();
|
||
|
|
||
|
if (AnimancerEvent.Sequence.Serializable.HasPersistentCalls(callback))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
callback = null;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|