예제 #1
0
                private void AddCalculateThresholdsFunction(GenericMenu menu, string label, int axis,
                                                            Func <AnimationClip, float, float> calculateThreshold)
                {
                    AddPropertyModifierFunction(menu, label, (property) =>
                    {
                        var count = CurrentClips.arraySize;
                        for (int i = 0; i < count; i++)
                        {
                            var clip = CurrentClips.GetArrayElementAtIndex(i).objectReferenceValue as AnimationClip;
                            if (clip == null)
                            {
                                continue;
                            }

                            var threshold = CurrentThresholds.GetArrayElementAtIndex(i);

                            var value    = threshold.vector2Value;
                            var newValue = calculateThreshold(clip, value[axis]);
                            if (!float.IsNaN(newValue))
                            {
                                value[axis] = newValue;
                            }
                            threshold.vector2Value = value;
                        }
                    });
                }
예제 #2
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(ReorderableList list)
                {
                    var index = CurrentClips.arraySize;

                    CurrentClips.InsertArrayElementAtIndex(index);

                    if (CurrentSpeeds.arraySize > 0)
                    {
                        CurrentSpeeds.InsertArrayElementAtIndex(index);
                    }
                }
예제 #3
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[CurrentClips.arraySize];

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

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

                    for (int i = 0; i < lengths.Length; i++)
                    {
                        var clip = CurrentClips.GetArrayElementAtIndex(i).objectReferenceValue as AnimationClip;
                        if (clip != null && clip.length > 0)
                        {
                            nonZeroLengths++;
                            totalLength += clip.length;
                            lengths[i]   = clip.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;
                    InitialiseSpeeds(speedCount);

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

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

                    TryCollapseSpeeds();
                }
예제 #4
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 > CurrentClips.arraySize)
                    {
                        return;
                    }

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

                    DoElementGUI(area, index, clip, speed);
                }
예제 #5
0
                /************************************************************************************************************************/

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

                            var threshold = CurrentThresholds.GetArrayElementAtIndex(i);

                            threshold.floatValue = calculateThreshold(clip, threshold.floatValue);
                        }
                    });
                }
                /************************************************************************************************************************/
                #endregion
                /************************************************************************************************************************/
                #region Sync
                /************************************************************************************************************************/

                /// <summary>Draws a "Sync" header.</summary>
                protected static void DoSyncHeaderGUI(Rect area)
                {
                    var content = Editor.AnimancerGUI.TempContent("Sync",
                                                                  "Determines which child states have their normalized times constantly synchronised");

                    DoHeaderDropdownGUI(area, CurrentSpeeds, content, (menu) =>
                    {
                        var syncCount = CurrentSynchroniseChildren.arraySize;

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

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

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

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

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

                            for (int i = 0; i < count; i++)
                            {
                                var clip = CurrentClips.GetArrayElementAtIndex(i).objectReferenceValue as AnimationClip;
                                if (clip == null)
                                {
                                    continue;
                                }

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

                                CurrentSynchroniseChildren.GetArrayElementAtIndex(i).boolValue =
                                    clip.averageSpeed != Vector3.zero;
                            }

                            TryCollapseSync();
                        });
                    });
                }