// 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
{
///
/// An object that holds a serialized callback (a by default) so that empty ones can be
/// drawn in the GUI without allocating array space for them until they actually contain something.
///
internal sealed class DummySerializableCallback : ScriptableObject
{
/************************************************************************************************************************/
[SerializeField] private SerializableCallbackHolder _Holder;
/************************************************************************************************************************/
private static SerializedProperty _CallbackProperty;
private static SerializedProperty CallbackProperty
{
get
{
if (_CallbackProperty == null)
{
var instance = CreateInstance();
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