예제 #1
0
        public override void OnInspectorGUI()
        {
            bool rebuildTrack = false;

            base.OnInspectorGUI();

            serializedObject.Update();

            if (_animationClip.objectReferenceValue == null)
            {
                EditorGUILayout.HelpBox("There's no Animation Clip", MessageType.Warning);
                Rect helpBoxRect = GUILayoutUtility.GetLastRect();

                float yCenter = helpBoxRect.center.y;

                helpBoxRect.xMax  -= 3;
                helpBoxRect.xMin   = helpBoxRect.xMax - 50;
                helpBoxRect.yMin   = yCenter - 12.5f;
                helpBoxRect.height = 25f;

                FAnimationTrack animTrack = (FAnimationTrack)_animEvent.Track;

                if (animTrack.AnimatorController == null || animTrack.LayerId == -1)
                {
                    GUI.enabled = false;
                }

                if (GUI.Button(helpBoxRect, "Create"))
                {
                    CreateAnimationClip(_animEvent);
                }

                GUI.enabled = true;
            }

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(_animationClip);

            Rect animationClipRect = GUILayoutUtility.GetLastRect();

            if (Event.current.type == EventType.DragUpdated && animationClipRect.Contains(Event.current.mousePosition))
            {
                int numAnimations = NumAnimationsDragAndDrop(_animEvent.Sequence.FrameRate);
                if (numAnimations > 0)
                {
                    DragAndDrop.visualMode = DragAndDropVisualMode.Link;
                }
            }
            else if (Event.current.type == EventType.DragPerform && animationClipRect.Contains(Event.current.mousePosition))
            {
                if (NumAnimationsDragAndDrop(_animEvent.Sequence.FrameRate) > 0)
                {
                    DragAndDrop.AcceptDrag();
                    AnimationClip clip = GetAnimationClipDragAndDrop(_animEvent.Sequence.FrameRate);
                    if (clip != null)
                    {
                        _animationClip.objectReferenceValue = clip;
                    }
                }
            }

            if (EditorGUI.EndChangeCheck())
            {
                AnimationClip clip = (AnimationClip)_animationClip.objectReferenceValue;
                if (clip)
                {
                    if (clip.frameRate != _animEvent.Track.Timeline.Sequence.FrameRate)
                    {
                        Debug.LogError(string.Format("Can't add animation, it has a different frame rate from the sequence ({0} vs {1})",
                                                     clip.frameRate, _animEvent.Track.Timeline.Sequence.FrameRate));

                        _animationClip.objectReferenceValue = null;
                    }
                    else
                    {
                        SerializedProperty frameRangeEnd = _frameRange.FindPropertyRelative("_end");
                        FrameRange         maxFrameRange = _animEvent.GetMaxFrameRange();
                        frameRangeEnd.intValue = Mathf.Min(_animEvent.FrameRange.Start + Mathf.RoundToInt(clip.length * clip.frameRate), maxFrameRange.End);
                    }

                    rebuildTrack = true;
                }
                else
                {
                    CheckDeleteAnimation(_animEvent);
                }
            }

            bool isAnimationEditable = Flux.FUtility.IsAnimationEditable(_animEvent._animationClip);

            if (isAnimationEditable)
            {
                EditorGUILayout.PropertyField(_controlsAnimation);
            }
            else
            {
                if (_controlsAnimation.boolValue)
                {
                    _controlsAnimation.boolValue = false;
                }
            }

            if (!_controlsAnimation.boolValue)
            {
                if (_animEvent.IsBlending())
                {
                    float offset      = _startOffset.intValue / _animEvent._animationClip.frameRate;
                    float blendFinish = offset + (_blendLength.intValue / _animEvent._animationClip.frameRate);

                    EditorGUILayout.BeginHorizontal();

                    EditorGUILayout.BeginHorizontal(GUILayout.Width(EditorGUIUtility.labelWidth - 5));                     // hack to get around some layout issue with imgui
                    _showBlendAndOffsetContent = EditorGUILayout.Foldout(_showBlendAndOffsetContent, new GUIContent("Offset+Blend"));
                    EditorGUILayout.EndHorizontal();

                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.MinMaxSlider(ref offset, ref blendFinish, 0, _animEvent.GetMaxStartOffset() / _animEvent._animationClip.frameRate + _animEvent.LengthTime);
                    if (EditorGUI.EndChangeCheck())
                    {
                        _startOffset.intValue = Mathf.Clamp(Mathf.RoundToInt(offset * _animEvent.Sequence.FrameRate), 0, _animEvent.GetMaxStartOffset());
                        _blendLength.intValue = Mathf.Clamp(Mathf.RoundToInt((blendFinish - offset) * _animEvent.Sequence.FrameRate), 0, _animEvent.Length);
                        rebuildTrack          = true;
                    }

                    EditorGUILayout.EndHorizontal();

                    if (_showBlendAndOffsetContent)
                    {
                        EditorGUI.BeginChangeCheck();
                        ++EditorGUI.indentLevel;
                        if (!isAnimationEditable)
                        {
                            EditorGUILayout.IntSlider(_startOffset, 0, _animEvent.GetMaxStartOffset());
                        }

                        //			if( _animEvent.IsBlending() )
                        {
                            EditorGUILayout.IntSlider(_blendLength, 0, _animEvent.Length);
                        }
                        --EditorGUI.indentLevel;
                        if (EditorGUI.EndChangeCheck())
                        {
                            rebuildTrack = true;
                        }
                    }
                }
                else
                {
                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.IntSlider(_startOffset, 0, _animEvent.GetMaxStartOffset());
                    if (EditorGUI.EndChangeCheck())
                    {
                        rebuildTrack = true;
                    }
                }
            }

            serializedObject.ApplyModifiedProperties();

            if (rebuildTrack)
            {
                FAnimationTrackInspector.RebuildStateMachine((FAnimationTrack)_animEvent.Track);
            }
        }
예제 #2
0
        private void UpdateEventFromController()
        {
            bool isBlending = _animEvt.IsBlending();

            if (isBlending)
            {
//				FPlayAnimationEvent prevAnimEvt = (FPlayAnimationEvent)_animTrack.GetEvents()[_animEvt.GetId() - 1];

                if (_transitionToState == null)
                {
                    _transitionToState = FAnimationTrackInspector.GetTransitionTo(_animEvt);

                    if (_transitionToState == null)
                    {
//						if( animTrackEditor.PreviewInSceneView )
//							animTrackEditor.ClearPreview();
                        FAnimationTrackInspector.RebuildStateMachine((FAnimationTrack)_trackEditor._track);

                        _transitionToState = FAnimationTrackInspector.GetTransitionTo(_animEvt);
                    }
                }

                if (_transitionSO == null)
                {
                    if (_transitionToState != null)
                    {
                        _transitionSO = new SerializedObject(_transitionToState);
                        //					SerializedProperty p = _transitionSO.GetIterator();
                        //
                        //					while( p.Next( true ) )
                        //						Debug.Log (p.propertyPath );
                        _transitionDuration   = _transitionSO.FindProperty("m_TransitionDuration");
                        _transitionOffset     = _transitionSO.FindProperty("m_TransitionOffset");
                        _transitionConditions = _transitionSO.FindProperty("m_Conditions");
                    }
                }
                else if (_transitionSO.targetObject == null)
                {
                    _transitionDuration   = null;
                    _transitionOffset     = null;
                    _transitionConditions = null;
                    _transitionSO         = null;
                }
            }
            else
            {
                if (_transitionToState != null || _transitionSO != null)
                {
                    _transitionToState    = null;
                    _transitionSO         = null;
                    _transitionOffset     = null;
                    _transitionDuration   = null;
                    _transitionConditions = null;
                }
            }

            if (_transitionSO != null)
            {
                _transitionSO.Update();
                _animEvtSO.Update();

                FPlayAnimationEvent prevAnimEvt = (FPlayAnimationEvent)_animTrack.GetEvents()[_animEvt.GetId() - 1];

                AnimationClip prevAnimEvtClip = prevAnimEvt._animationClip;
                if (prevAnimEvtClip != null)
                {
                    float exitTimeNormalized = (prevAnimEvt.Length / prevAnimEvtClip.frameRate) / prevAnimEvtClip.length;

                    SerializedProperty exitTime = _transitionConditions.GetArrayElementAtIndex(0).FindPropertyRelative("m_ExitTime");

                    if (!Mathf.Approximately(exitTimeNormalized, exitTime.floatValue))
                    {
                        exitTime.floatValue = exitTimeNormalized;
                    }

                    float blendNormalized = (_blendLength.intValue / prevAnimEvtClip.frameRate) / prevAnimEvtClip.length;

                    if (!Mathf.Approximately(blendNormalized, _transitionDuration.floatValue))
                    {
                        _blendLength.intValue = Mathf.Clamp(Mathf.RoundToInt(_transitionDuration.floatValue * prevAnimEvtClip.length * prevAnimEvtClip.frameRate), 0, _animEvt.Length);

                        _transitionDuration.floatValue = (_blendLength.intValue / prevAnimEvtClip.frameRate) / prevAnimEvtClip.length;

                        _animEvtSO.ApplyModifiedProperties();
                    }
                }

                _transitionSO.ApplyModifiedProperties();
            }
        }
예제 #3
0
        public static void RebuildStateMachine(FAnimationTrack track)
        {
            if (track.AnimatorController == null || track.LayerId == -1)
            {
                return;
            }

            bool isPreviewing = track.HasCache;

            if (isPreviewing)
            {
                track.ClearCache();
            }

            Animator animator = track.Owner.GetComponent <Animator>();

            animator.runtimeAnimatorController = null;

            AnimatorController controller = (AnimatorController)track.AnimatorController;

            track.UpdateEventIds();

            AnimatorControllerLayer layer = FindLayer(controller, track.LayerName);

            if (layer == null)
            {
                controller.AddLayer(track.LayerName);
                layer = FindLayer(controller, track.LayerName);
            }

            AnimatorStateMachine fluxSM = FindStateMachine(layer.stateMachine, FLUX_STATE_MACHINE_NAME);

            if (fluxSM == null)
            {
                fluxSM = layer.stateMachine.AddStateMachine(FLUX_STATE_MACHINE_NAME);

                ChildAnimatorStateMachine[] stateMachines = layer.stateMachine.stateMachines;

                for (int i = 0; i != stateMachines.Length; ++i)
                {
                    if (stateMachines[i].stateMachine == fluxSM)
                    {
                        stateMachines[i].position = layer.stateMachine.entryPosition + new Vector3(300, 0, 0);
                        break;
                    }
                }
                layer.stateMachine.stateMachines = stateMachines;
            }

            List <FEvent> events = track.Events;

            if (fluxSM.states.Length > events.Count)
            {
                for (int i = events.Count; i < fluxSM.states.Length; ++i)
                {
                    fluxSM.RemoveState(fluxSM.states[i].state);
                }
            }
            else if (fluxSM.states.Length < events.Count)
            {
                for (int i = fluxSM.states.Length; i < events.Count; ++i)
                {
                    fluxSM.AddState(i.ToString());
                }
            }

            AnimatorState lastState = null;
            Vector3       pos       = fluxSM.entryPosition + new Vector3(300, 0, 0);

            Vector3 statePosDelta = new Vector3(0, 80, 0);

            ChildAnimatorState[] states = fluxSM.states;

            for (int i = 0; i != events.Count; ++i)
            {
                FPlayAnimationEvent animEvent = (FPlayAnimationEvent)events[i];

                if (animEvent._animationClip == null) // dump events without animations
                {
                    continue;
                }

                states[i].position = pos;

                AnimatorState state = states[i].state;

                state.name = i.ToString();

                pos += statePosDelta;

                state.motion = animEvent._animationClip;

                animEvent._stateHash = Animator.StringToHash(state.name);

                if (lastState)
                {
                    AnimatorStateTransition[] lastStateTransitions = lastState.transitions;

                    if (animEvent.IsBlending())
                    {
                        AnimatorStateTransition transition = null;

                        for (int j = lastStateTransitions.Length - 1; j > 0; --j)
                        {
                            lastState.RemoveTransition(lastStateTransitions[j]);
                        }

                        transition = lastStateTransitions.Length == 1 ? lastStateTransitions[0] : lastState.AddTransition(state);

                        transition.offset = (animEvent._startOffset / animEvent._animationClip.frameRate) / animEvent._animationClip.length;

                        FPlayAnimationEvent prevAnimEvent = (FPlayAnimationEvent)events[i - 1];

                        int offsetFrame = Mathf.RoundToInt(transition.offset * animEvent._animationClip.length * animEvent._animationClip.frameRate);
                        animEvent._startOffset = Mathf.Clamp(offsetFrame, 0, animEvent.GetMaxStartOffset());
                        transition.offset      = (animEvent._startOffset / animEvent._animationClip.frameRate) / animEvent._animationClip.length;
                        EditorUtility.SetDirty(animEvent);

                        float blendSeconds = animEvent._blendLength / prevAnimEvent._animationClip.frameRate;
                        transition.duration = blendSeconds;

                        transition.hasExitTime = true;
                        float p = blendSeconds / prevAnimEvent._animationClip.length;
                        transition.exitTime = p > 1f ? 1f : 1f - Mathf.Clamp01(blendSeconds / prevAnimEvent._animationClip.length);

                        for (int j = transition.conditions.Length - 1; j >= 0; --j)
                        {
                            transition.RemoveCondition(transition.conditions[j]);
                        }

                        //						AnimatorCondition condition = transition.conditions[0];
                        //						condition.threshold = 0;
                    }
                    else // animations not blending, needs hack for animation previewing
                    {
                        for (int j = lastStateTransitions.Length - 1; j >= 0; --j)
                        {
                            lastState.RemoveTransition(lastStateTransitions[j]);
                        }
                    }
                }

                lastState = state;
            }

            fluxSM.states = states;

            if (fluxSM.states.Length > 0)
            {
                layer.stateMachine.defaultState = fluxSM.states[0].state;
            }

            animator.runtimeAnimatorController = controller;

            if (isPreviewing)
            {
                track.CreateCache();
            }
        }
예제 #4
0
        public override void OnInspectorGUI()
        {
            bool rebuildTrack = false;

            base.OnInspectorGUI();

            serializedObject.Update();

            if (_animationClip.objectReferenceValue == null)
            {
                EditorGUILayout.HelpBox("无动画剪辑Clip", MessageType.Warning);
            }

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(_animationClip, _animationClipUI);

            Rect animationClipRect = GUILayoutUtility.GetLastRect();

            if (Event.current.type == EventType.DragUpdated && animationClipRect.Contains(Event.current.mousePosition))
            {
                int numAnimations = NumAnimationsDragAndDrop(_animEvent.Sequence.FrameRate);
                if (numAnimations > 0)
                {
                    DragAndDrop.visualMode = DragAndDropVisualMode.Link;
                }
            }
            else if (Event.current.type == EventType.DragPerform && animationClipRect.Contains(Event.current.mousePosition))
            {
                if (NumAnimationsDragAndDrop(_animEvent.Sequence.FrameRate) > 0)
                {
                    DragAndDrop.AcceptDrag();
                    AnimationClip clip = GetAnimationClipDragAndDrop(_animEvent.Sequence.FrameRate);
                    if (clip != null)
                    {
                        _animationClip.objectReferenceValue = clip;
                    }
                }
            }

            if (EditorGUI.EndChangeCheck())
            {
                AnimationClip clip = (AnimationClip)_animationClip.objectReferenceValue;
                if (clip)
                {
                    if (clip.frameRate != _animEvent.Track.Container.Sequence.FrameRate)
                    {
                        Debug.LogError(string.Format("Can't add animation, it has a different frame rate from the sequence ({0} vs {1})",
                                                     clip.frameRate, _animEvent.Track.Container.Sequence.FrameRate));

                        _animationClip.objectReferenceValue = null;
                    }
                    else
                    {
                        SerializedProperty frameRangeEnd = _frameRange.FindPropertyRelative("_end");
                        FrameRange         maxFrameRange = _animEvent.GetMaxFrameRange();
                        frameRangeEnd.intValue = Mathf.Min(_animEvent.FrameRange.Start + Mathf.RoundToInt(clip.length * clip.frameRate), maxFrameRange.End);
                    }

                    rebuildTrack = true;
                }
                else
                {
                    CheckDeleteAnimation(_animEvent);
                }
            }

            if (_animEvent.IsBlending())
            {
                int id = _animEvent.GetId();
                FPlayAnimationEvent preAnimEvt = _animEvent.Track.Events[id - 1] as FPlayAnimationEvent;
                if (id > 0)
                {
                    EditorGUI.BeginChangeCheck();
                    EditorGUILayout.IntSlider(_startOffset, 0, _animEvent.GetMaxStartOffset(), _startOffsetUI);
                    EditorGUILayout.IntSlider(_blendLength, 0, preAnimEvt.Length > _animEvent.Length ? _animEvent.Length : preAnimEvt.Length, _blendLengthUI);
                    if (EditorGUI.EndChangeCheck())
                    {
                        rebuildTrack = true;
                    }
                }
            }
            else
            {
                EditorGUI.BeginChangeCheck();
                EditorGUILayout.IntSlider(_startOffset, 0, _animEvent.GetMaxStartOffset(), _startOffsetUI);
                if (EditorGUI.EndChangeCheck())
                {
                    rebuildTrack = true;
                }
            }
            serializedObject.ApplyModifiedProperties();

            if (rebuildTrack)
            {
                FAnimationTrackInspector.RebuildStateMachine((FAnimationTrack)_animEvent.Track);
            }
        }