Пример #1
0
        public int AddState(AnimationPlayerState state, Dictionary <string, float> blendVariableValues)
        {
            if (states.Count == 0)
            {
                state.RegisterUsedBlendVarsIn(blendVariableValues);
                HandleAddedFirstStateAfterStartup(state, blendVariableValues);
                return(0);
            }

            states.Add(state);
            if (state.animationEvents.Count > 0)
            {
                anyStatesHasAnimationEvents = true;
            }
            var playable = state.Initialize(containingGraph, varTo1DBlendControllers, varTo2DBlendControllers, all2DControllers, clipSwapCollections);

            var indexOfNew = states.Count - 1;

            stateNameToIdx[state.Name] = indexOfNew;

            Array.Resize(ref runtimePlayables, runtimePlayables.Length + 1);
            runtimePlayables[runtimePlayables.Length - 1] = playable;

            activeWhenBlendStarted.Add(false);
            valueWhenBlendStarted.Add(0f);
            timeLastFrame.Add(0d);

            var newLookup = new int[states.Count, states.Count];

            for (int i = 0; i < transitionLookup.GetLength(0); i++)
            {
                for (int j = 0; j < transitionLookup.GetLength(1); j++)
                {
                    newLookup[i, j] = transitionLookup[i, j];
                }
            }

            for (int i = 0; i < states.Count; i++)
            {
                newLookup[i, indexOfNew] = -1;
                newLookup[indexOfNew, i] = -1;
            }

            transitionLookup = newLookup;

            stateMixer.SetInputCount(stateMixer.GetInputCount() + 1);

            //Shift all excess playables (ie blend helpers) one index up. Since their order doesn't count, could just swap the first one to the last index?
            for (int i = stateMixer.GetInputCount() - 1; i > states.Count; i--)
            {
                var p      = stateMixer.GetInput(i);
                var weight = stateMixer.GetInputWeight(i);
                containingGraph.Disconnect(stateMixer, i - 1);
                containingGraph.Connect(p, 0, stateMixer, i);
                stateMixer.SetInputWeight(i, weight);
            }

            containingGraph.Connect(playable, 0, stateMixer, indexOfNew);
            return(indexOfNew);
        }
Пример #2
0
        private void DrawCurrentSelectedState(AnimationStateWrapper.Type type)
        {
            bool markDirty = false;

            StateDataDrawer.ReloadCheck();
            AnimationPlayerState selectedState = null;

            if (type == AnimationStateWrapper.Type.BlendTree1D)
            {
                selectedState = animationStateWrapper.blendTree1D;
            }
            else if (type == AnimationStateWrapper.Type.BlendTree2D)
            {
                selectedState = animationStateWrapper.blendTree2D;
            }
            else if (type == AnimationStateWrapper.Type.PlayRandomClip)
            {
                selectedState = animationStateWrapper.playRandomClip;
            }
            else if (type == AnimationStateWrapper.Type.SingleClip)
            {
                selectedState = animationStateWrapper.singleClip;
            }

            if (selectedState != null)
            {
                StateDataDrawer.DrawStateData(selectedState, ref markDirty);
            }

            if (markDirty)
            {
                EditorUtility.SetDirty(animationStateWrapper);
            }
        }
Пример #3
0
        private static void DrawTransitionSelection(AnimationLayer layer, AnimationPlayerState selectedState, string fromStateName,
                                                    StateTransition selectedTransition, Action <StateTransition> SetSelectedTransition)
        {
            transitionsFromState.Clear();
            foreach (var transition in layer.transitions)
            {
                if (transition.FromState == selectedState)
                {
                    transitionsFromState.Add(transition);
                }
            }

            transitionsFromState.Sort((t1, t2) => t1.ToState.Name.CompareTo(t2.ToState.Name)); //@TODO: Grab hold of NaturalComparrison from Mesmer, use it, so state_2 doesn't sort under state_11

            if (transitionsFromState.Count == 0)
            {
                EditorGUILayout.LabelField($"No defined transitions from {fromStateName}");
            }
            else
            {
                EditorGUILayout.LabelField($"Transitions from {fromStateName}:");

                var buttonWidth = 100f;
                foreach (var transition in transitionsFromState)
                {
                    var width = GUI.skin.button.CalcSize(new GUIContent(transition.name)).x + 20f;
                    buttonWidth = Mathf.Max(width, buttonWidth);
                }

                EditorGUILayout.Space();
                AnimationPlayerState lastToState = null;

                EditorUtilities.DrawIndented(() => {
                    for (var i = 0; i < transitionsFromState.Count; i++)
                    {
                        var transition = transitionsFromState[i];
                        if (transition.ToState != lastToState)
                        {
                            lastToState = transition.ToState;
                            EditorGUILayout.LabelField($"Transitions to {lastToState.Name}");
                        }

                        using (new GUILayout.HorizontalScope())
                            using (new EditorGUI.DisabledScope(transition == selectedTransition)) {
                                if (GUILayout.Button(transition.name, GUILayout.Width(buttonWidth)))
                                {
                                    SetSelectedTransition(transition);
                                }

                                if (transition.isDefault)
                                {
                                    EditorGUILayout.LabelField("(Default)");
                                }
                            }
                    }
                });
            }
        }
Пример #4
0
        /// <summary>
        /// Adds a new state to the AnimationPlayer, and makes sure that all the graphs are correctly setup.
        /// At edit time, just add new states directly into the layer's states
        /// </summary>
        /// <param name="state">State to add.</param>
        /// <param name="layer">Layer to add the state to.</param>
        /// <returns>The index of the added state</returns>
        public int AddState(AnimationPlayerState state, int layer = 0)
        {
            if (!Application.isPlaying)
            {
                Debug.LogError("Don't call AnimationPlayer.AddState at runtime! Just add states to the layers directly!");
                return(-1);
            }

            return(layers[layer].AddState(state, blendVariableValues));
        }
Пример #5
0
        private void AddAllClipsFromStateTo(AnimationPlayerState state, List <AnimationClip> list)
        {
            switch (state)
            {
            case BlendTree1D blendTree1D:
            {
                foreach (var clip in blendTree1D.blendTree.Select(entry => entry.clip))
                {
                    AddClip(clip);
                }
                break;
            }

            case BlendTree2D blendTree2D:
            {
                foreach (var clip in blendTree2D.blendTree.Select(entry => entry.clip))
                {
                    AddClip(clip);
                }
                break;
            }

            case PlayRandomClip playRandomClip:
            {
                foreach (var clip in playRandomClip.clips)
                {
                    AddClip(clip);
                }
                break;
            }

            case Sequence sequence:
            {
                foreach (var clip in sequence.clips)
                {
                    AddClip(clip);
                }
                break;
            }

            case SingleClip singleClip:
            {
                AddClip(singleClip.clip);
                break;
            }
            }

            void AddClip(AnimationClip clip)
            {
                if (clip != null && !list.Contains(clip))
                {
                    list.Add(clip);
                }
            }
        }
Пример #6
0
        private int CompareListIndices(AnimationPlayerState x, AnimationPlayerState y)
        {
            var xIndex = Array.IndexOf(serializedStateOrder, x.GUID);
            var yIndex = Array.IndexOf(serializedStateOrder, y.GUID);

            if (xIndex < yIndex)
            {
                return(-1);
            }
            return(xIndex > yIndex ? 1 : 0);
        }
Пример #7
0
        public (AnimationClip, float) GetCurrentActualClipAndWeight(AnimationPlayerState state, int clipIndex = 0)
        {
            var stateIndex = states.IndexOf(state);

            if (stateIndex == -1)
            {
                Debug.LogError($"The state {state} is not on this layer!");
                return(null, -1);
            }

            return(GetCurrentActualClipAndWeight(stateIndex, clipIndex));
        }
Пример #8
0
        /// <summary>
        /// If the first state gets added after Initialize and InitializeLayerBlending has run, we disconnect and destroy the empty state mixer, and then
        /// re-initialize.
        /// </summary>
        private void HandleAddedFirstStateAfterStartup(AnimationPlayerState state, Dictionary <string, float> blendVariableValues)
        {
            states.Add(state);

            // layerMixer.IsValid => there's more than 1 layer.
            if (layerMixer.IsValid())
            {
                containingGraph.Disconnect(layerMixer, layerIndex);
            }

            stateMixer.Destroy();

            InitializeSelf(containingGraph, defaultTransition, clipSwapCollections, blendVariableValues);

            if (layerMixer.IsValid())
            {
                InitializeLayerBlending(containingGraph, layerIndex, layerMixer);
            }
        }
Пример #9
0
        public static void DrawStateData(AnimationPlayerState state, ref bool markDirty)
        {
            const float labelWidth = 55f;

            var old = state.Name;

            state.Name = EditorUtilities.TextField("Name", state.Name, labelWidth);
            if (old != state.Name)
            {
                markDirty = true;
            }

            state.speed = EditorUtilities.DoubleField("Speed", state.speed, labelWidth);

            switch (state)
            {
            case SingleClip singleClipState:
                DrawSingleClipState(singleClipState, ref markDirty, labelWidth);
                break;

            case BlendTree1D blendTree1D:
                Draw1DBlendTree(blendTree1D, ref markDirty);
                break;

            case BlendTree2D blendTree2D:
                Draw2DBlendTree(blendTree2D, ref markDirty);
                break;

            case PlayRandomClip playRandom:
                DrawSelectRandomState(playRandom, ref markDirty);
                break;

            case Sequence sequence:
                DrawSequence(sequence, ref markDirty);
                break;

            default:
                EditorGUILayout.LabelField($"Unknown animation state type: {(state == null ? "null" : state.GetType().Name)}");
                break;
            }
        }
Пример #10
0
        private static IEnumerable <AnimationClip> GetClips(AnimationPlayerState state)
        {
            switch (state)
            {
            case BlendTree1D blendTree1D:
                foreach (var clip in blendTree1D.blendTree.Select(entry => entry.clip))
                {
                    yield return(clip);
                }
                break;

            case BlendTree2D blendTree2D:
                foreach (var clip in blendTree2D.blendTree.Select(entry => entry.clip))
                {
                    yield return(clip);
                }
                break;

            case PlayRandomClip playRandomClip:
                foreach (var clip in playRandomClip.clips)
                {
                    yield return(clip);
                }
                break;

            case Sequence sequence:
                foreach (var clip in sequence.clips)
                {
                    yield return(clip);
                }
                break;

            case SingleClip singleClip:
                yield return(singleClip.clip);

                break;
            }
        }
Пример #11
0
 private static void DrawCreateNewTransition(AnimationPlayer animationPlayer, Action <StateTransition> SetSelectedTransition, string[] stateNamesInLayer,
                                             string fromStateName, string toStateName, AnimationPlayerState selectedState, AnimationLayer layer)
 {
     using (new EditorGUILayout.HorizontalScope()) {
         GUILayout.FlexibleSpace();
         if (GUILayout.Button($"Create new transition from {fromStateName}"))
         {
             GenericMenu menu = new GenericMenu();
             foreach (var state in stateNamesInLayer)
             {
                 menu.AddItem(new GUIContent($"Transition from {fromStateName} to {state}"), false, () => {
                     //@TODO: If this is the first transition between the states, it should be set as default.
                     EditorUtilities.RecordUndo(animationPlayer, $"Adding transition from {fromStateName} to {toStateName}");
                     var newState = new StateTransition {
                         FromState      = selectedState,
                         ToState        = layer.states.Find(s => s.Name == state),
                         transitionData = TransitionData.Linear(.2f)
                     };
                     layer.transitions.Add(newState);
                     SetSelectedTransition(newState);
                 });
             }
             menu.ShowAsContext();
         }
     }
 }
Пример #12
0
        private static List <StateTransition> GetTransitionsBetweenStates(AnimationLayer layer, AnimationPlayerState selectedState, AnimationPlayerState selectedToState)
        {
            var allTransitionsBetweenStates = new List <StateTransition>();

            foreach (var transition in layer.transitions)
            {
                if (transition.FromState == selectedState && transition.ToState == selectedToState)
                {
                    allTransitionsBetweenStates.Add(transition);
                }
            }
            return(allTransitionsBetweenStates);
        }