/************************************************************************************************************************/ /// <summary>[<see cref="IDisposable"/>] /// Reduces the <see cref="Callbacks"/> array size to remove any empty elements. /// </summary> public void Dispose() { if (_TimeCount == 1 && _CallbackCount == 0 && float.IsNaN(GetTime(0).floatValue)) { Times.arraySize = 0; } else { var callbackCount = _CallbackCount; if (callbackCount > _TimeCount) { callbackCount = _TimeCount; } while (callbackCount > 0) { var callbackProperty = GetCallback(callbackCount - 1); var callback = Serialization.GetValue(callbackProperty); if (callback != null && EventSequence.HasPersistentCalls(callback)) { break; } else { callbackCount--; } } if (callbackCount != _CallbackCount) { Callbacks.arraySize = callbackCount; } } if (EditorGUI.EndChangeCheck()) { Property.serializedObject.ApplyModifiedProperties(); } Property = null; }
/************************************************************************************************************************/ /// <summary>Draws the GUI fields for the event at the specified `index`.</summary> public static void DoCallbackGUI(ref Rect area, Context context, int index, bool autoSort, string callbackLabel) { EditorGUI.BeginChangeCheck(); using (ObjectPool.Disposable.AcquireContent(out var label, callbackLabel)) { if (index < context.Callbacks.Count) { var callback = context.Callbacks.GetElement(index); area.height = EditorGUI.GetPropertyHeight(callback, false); EditorGUI.BeginProperty(area, GUIContent.none, callback); // 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, callback, label, false); EditorGUI.indentLevel = indentLevel; EditorGUI.EndProperty(); } else if (DummySerializableCallback.DoCallbackGUI(ref area, label, context.Callbacks.Property, out var callback)) { try { Sequence.DisableCompactArrays = true; if (index >= context.Times.Count) { context.Times.Property.InsertArrayElementAtIndex(index); context.Times.Count++; context.Times.GetElement(index).floatValue = float.NaN; context.Times.Property.serializedObject.ApplyModifiedProperties(); } context.Callbacks.Property.ForEachTarget((callbacksProperty) => { var accessor = callbacksProperty.GetAccessor(); var oldCallbacks = (Array)accessor.GetValue(callbacksProperty.serializedObject.targetObject); Array newCallbacks; if (oldCallbacks == null) { var elementType = accessor.GetFieldElementType(callbacksProperty); newCallbacks = Array.CreateInstance(elementType, 1); } else { var elementType = oldCallbacks.GetType().GetElementType(); newCallbacks = Array.CreateInstance(elementType, index + 1); Array.Copy(oldCallbacks, newCallbacks, oldCallbacks.Length); } newCallbacks.SetValue(callback, index); accessor.SetValue(callbacksProperty, newCallbacks); }); context.Callbacks.Property.OnPropertyChanged(); context.Callbacks.Refresh(); } finally { Sequence.DisableCompactArrays = false; } } } if (EditorGUI.EndChangeCheck()) { if (index < context.Callbacks.Count) { var events = context.Sequence?.InitializedEvents; if (events != null) { var animancerEvent = index < events.Count ? events[index] : events.endEvent; if (AnimancerEvent.IsNullOrDummy(animancerEvent.callback)) { context.Callbacks.Property.serializedObject.ApplyModifiedProperties(); var property = context.Callbacks.GetElement(index); var callback = property.GetValue(); var invoker = Sequence.GetInvoker(callback); if (index < events.Count) { events.SetCallback(index, invoker); } else { events.OnEnd = invoker; } } } } } AnimancerGUI.NextVerticalArea(ref area); }