Ejemplo n.º 1
0
            /************************************************************************************************************************/

            /// <summary>
            /// Recalculates the <see cref="CurrentSpeeds"/> depending on the <see cref="AnimationClip.length"/> of
            /// their animations so that they all take the same amount of time to play fully.
            /// </summary>
            private static void NormalizeDurations(SerializedProperty property)
            {
                var speedCount = CurrentSpeeds.arraySize;

                var lengths = new float[CurrentAnimations.arraySize];

                if (lengths.Length <= 1)
                {
                    return;
                }

                int   nonZeroLengths = 0;
                float totalLength    = 0;
                float totalSpeed     = 0;

                for (int i = 0; i < lengths.Length; i++)
                {
                    var state = CurrentAnimations.GetArrayElementAtIndex(i).objectReferenceValue;
                    if (AnimancerUtilities.TryGetLength(state, out var length) &&
                        length > 0)
                    {
                        nonZeroLengths++;
                        totalLength += length;
                        lengths[i]   = length;

                        if (speedCount > 0)
                        {
                            totalSpeed += CurrentSpeeds.GetArrayElementAtIndex(i).floatValue;
                        }
                    }
                }

                if (nonZeroLengths == 0)
                {
                    return;
                }

                var averageLength = totalLength / nonZeroLengths;
                var averageSpeed  = speedCount > 0 ? totalSpeed / nonZeroLengths : 1;

                CurrentSpeeds.arraySize = lengths.Length;
                InitializeSpeeds(speedCount);

                for (int i = 0; i < lengths.Length; i++)
                {
                    if (lengths[i] == 0)
                    {
                        continue;
                    }

                    CurrentSpeeds.GetArrayElementAtIndex(i).floatValue = averageSpeed * lengths[i] / averageLength;
                }

                TryCollapseArrays();
            }
Ejemplo n.º 2
0
            /************************************************************************************************************************/

            /// <summary>Draws the GUI of the state at the specified `index`.</summary>
            private void DoElementGUI(Rect area, int index, bool isActive, bool isFocused)
            {
                if (index < 0 || index > CurrentAnimations.arraySize)
                {
                    return;
                }

                var state = CurrentAnimations.GetArrayElementAtIndex(index);
                var speed = CurrentSpeeds.arraySize > 0 ? CurrentSpeeds.GetArrayElementAtIndex(index) : null;

                DoElementGUI(area, index, state, speed);
            }
Ejemplo n.º 3
0
            /// <summary>
            /// Called when adding a new state to the list to ensure that any other relevant arrays have new
            /// elements added as well.
            /// </summary>
            protected virtual void OnAddElement(int index)
            {
                CurrentAnimations.InsertArrayElementAtIndex(index);

                if (CurrentSpeeds.arraySize > 0)
                {
                    CurrentSpeeds.InsertArrayElementAtIndex(index);
                }

                if (CurrentSynchronizeChildren.arraySize > index)
                {
                    CurrentSynchronizeChildren.InsertArrayElementAtIndex(index);
                }
            }
            /************************************************************************************************************************/

            private void AddCalculateThresholdsFunction(UnityEditor.GenericMenu menu, string label,
                                                        Func <Object, float, float> calculateThreshold)
            {
                AddPropertyModifierFunction(menu, label, (property) =>
                {
                    var count = CurrentAnimations.arraySize;
                    for (int i = 0; i < count; i++)
                    {
                        var state = CurrentAnimations.GetArrayElementAtIndex(i).objectReferenceValue;
                        if (state == null)
                        {
                            continue;
                        }

                        var threshold = CurrentThresholds.GetArrayElementAtIndex(i);
                        var value     = calculateThreshold(state, threshold.floatValue);
                        if (!float.IsNaN(value))
                        {
                            threshold.floatValue = value;
                        }
                    }
                });
            }
Ejemplo n.º 5
0
            /************************************************************************************************************************/
            #endregion
            /************************************************************************************************************************/
            #region Sync
            /************************************************************************************************************************/

            /// <summary>Draws a "Sync" header.</summary>
            protected void DoSyncHeaderGUI(Rect area)
            {
                using (ObjectPool.Disposable.AcquireContent(out var label, "Sync",
                                                            "Determines which child states have their normalized times constantly synchronized"))
                {
                    DoHeaderDropdownGUI(area, CurrentSpeeds, label, (menu) =>
                    {
                        var syncCount = CurrentSynchronizeChildren.arraySize;

                        var allState = syncCount == 0 ? MenuFunctionState.Selected : MenuFunctionState.Normal;
                        AddPropertyModifierFunction(menu, "All", allState,
                                                    (_) => CurrentSynchronizeChildren.arraySize = 0);

                        var syncNone = syncCount == CurrentAnimations.arraySize;
                        if (syncNone)
                        {
                            for (int i = 0; i < syncCount; i++)
                            {
                                if (CurrentSynchronizeChildren.GetArrayElementAtIndex(i).boolValue)
                                {
                                    syncNone = false;
                                    break;
                                }
                            }
                        }
                        var noneState = syncNone ? MenuFunctionState.Selected : MenuFunctionState.Normal;
                        AddPropertyModifierFunction(menu, "None", noneState, (_) =>
                        {
                            var count = CurrentSynchronizeChildren.arraySize = CurrentAnimations.arraySize;
                            for (int i = 0; i < count; i++)
                            {
                                CurrentSynchronizeChildren.GetArrayElementAtIndex(i).boolValue = false;
                            }
                        });

                        AddPropertyModifierFunction(menu, "Invert", MenuFunctionState.Normal, (_) =>
                        {
                            var count = CurrentSynchronizeChildren.arraySize;
                            for (int i = 0; i < count; i++)
                            {
                                var property       = CurrentSynchronizeChildren.GetArrayElementAtIndex(i);
                                property.boolValue = !property.boolValue;
                            }

                            var newCount = CurrentSynchronizeChildren.arraySize = CurrentAnimations.arraySize;
                            for (int i = count; i < newCount; i++)
                            {
                                CurrentSynchronizeChildren.GetArrayElementAtIndex(i).boolValue = false;
                            }
                        });

                        AddPropertyModifierFunction(menu, "Non-Stationary", MenuFunctionState.Normal, (_) =>
                        {
                            var count = CurrentAnimations.arraySize;

                            for (int i = 0; i < count; i++)
                            {
                                var state = CurrentAnimations.GetArrayElementAtIndex(i).objectReferenceValue;
                                if (state == null)
                                {
                                    continue;
                                }

                                if (i >= syncCount)
                                {
                                    CurrentSynchronizeChildren.arraySize = i + 1;
                                    for (int j = syncCount; j < i; j++)
                                    {
                                        CurrentSynchronizeChildren.GetArrayElementAtIndex(j).boolValue = true;
                                    }
                                    syncCount = i + 1;
                                }

                                CurrentSynchronizeChildren.GetArrayElementAtIndex(i).boolValue =
                                    AnimancerUtilities.TryGetAverageVelocity(state, out var velocity) &&
                                    velocity != default;
                            }

                            TryCollapseSync();
                        });
                    });
                }
            }