Exemplo n.º 1
0
            /************************************************************************************************************************/

            /// <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);
        }