public static AnimatorStateTransition GetTransitionTo(FPlayAnimationEvent animEvt) { FAnimationTrack animTrack = (FAnimationTrack)animEvt.Track; if (animTrack.AnimatorController == null) { return(null); } AnimatorController controller = (AnimatorController)animTrack.AnimatorController; AnimatorState animState = null; AnimatorControllerLayer layer = FindLayer(controller, ((FAnimationTrack)animEvt.Track).LayerName); if (layer == null) { return(null); } if (layer.stateMachine.stateMachines.Length == 0) { return(null); } ChildAnimatorStateMachine fluxSM = layer.stateMachine.stateMachines[0]; AnimatorStateMachine stateMachine = fluxSM.stateMachine; for (int i = 0; i != stateMachine.states.Length; ++i) { if (stateMachine.states[i].state.nameHash == animEvt._stateHash) { animState = stateMachine.states[i].state; break; } } if (animState == null) { // Debug.LogError("Couldn't find state " + animEvt._animationClip ); return(null); } for (int i = 0; i != stateMachine.states.Length; ++i) { AnimatorState state = stateMachine.states[i].state; AnimatorStateTransition[] transitions = state.transitions; for (int j = 0; j != transitions.Length; ++j) { if (transitions[j].destinationState == animState) { return(transitions[j]); } } } return(null); }
public static void CheckDeleteAnimation(FPlayAnimationEvent animEvt) { if (animEvt._animationClip != null) { Undo.RecordObject(animEvt._animationClip, "DeleteAnimation"); } }
// public override void OnTogglePreview () // { //// int currentFrame = Track.Sequence.GetCurrentFrame(); // // base.OnTogglePreview(); // //// if( currentFrame >= 0 ) //// SequenceEditor.SetCurrentFrame( currentFrame ); // } public override void Render(Rect rect, float headerWidth) { // bool isPreviewing = _track.IsPreviewing; base.Render(rect, headerWidth); // if( isPreviewing != _track.IsPreviewing ) // { // if( Event.current.alt ) // SyncWithAnimationWindow = true; // } switch (Event.current.type) { case EventType.DragUpdated: if (rect.Contains(Event.current.mousePosition)) { int numAnimationsDragged = FAnimationEventInspector.NumAnimationsDragAndDrop(Track.Sequence.FrameRate); int frame = SequenceEditor.GetFrameForX(Event.current.mousePosition.x); DragAndDrop.visualMode = numAnimationsDragged > 0 && Track.CanAddAt(frame) ? DragAndDropVisualMode.Copy : DragAndDropVisualMode.Rejected; Event.current.Use(); } break; case EventType.DragPerform: if (rect.Contains(Event.current.mousePosition)) { AnimationClip animClip = FAnimationEventInspector.GetAnimationClipDragAndDrop(Track.Sequence.FrameRate); if (animClip && Mathf.Approximately(animClip.frameRate, Track.Sequence.FrameRate)) { int frame = SequenceEditor.GetFrameForX(Event.current.mousePosition.x); int maxLength; if (Track.CanAddAt(frame, out maxLength)) { FPlayAnimationEvent animEvt = FEvent.Create <FPlayAnimationEvent>(new FrameRange(frame, frame + Mathf.Min(maxLength, Mathf.RoundToInt(animClip.length * animClip.frameRate)))); Track.Add(animEvt); FAnimationEventInspector.SetAnimationClip(animEvt, animClip); DragAndDrop.AcceptDrag(); } } Event.current.Use(); } break; } // if( _wasPreviewing != _track.IsPreviewing ) // { // if( _wasPreviewing ) // SequenceEditor.OnUpdateEvent.RemoveListener( OnUpdate ); // else // SequenceEditor.OnUpdateEvent.AddListener( OnUpdate ); // // _wasPreviewing = _track.IsPreviewing; // } }
protected override void Init(FObject obj) { base.Init(obj); _animEvt = (FPlayAnimationEvent)_evt; _animTrack = (FAnimationTrack)_animEvt.GetTrack(); }
public static void SetAnimationClip(FPlayAnimationEvent animEvent, AnimationClip animClip) { FAnimationEventInspector editor = (FAnimationEventInspector)CreateEditor(animEvent, typeof(FAnimationEventInspector)); editor.SetAnimationClip(animClip); DestroyImmediate(editor); FAnimationTrackInspector.RebuildStateMachine((FAnimationTrack)animEvent.GetTrack()); }
public static void CheckDeleteAnimation(FPlayAnimationEvent animEvt) { if (animEvt._animationClip != null && Flux.FUtility.IsAnimationEditable(animEvt._animationClip) && /*AssetDatabase.IsSubAsset( animEvt._animationClip )*/ EditorUtility.DisplayDialog("Delete animation?", string.Format("The animation clip '{0}' is stored inside an animator controller, do you want to delete it?", animEvt._animationClip.name), "Delete", "Keep")) { Undo.DestroyObjectImmediate(animEvt._animationClip); AssetDatabase.SaveAssets(); } }
private void PreviewAnimationEvent(FAnimationEventEditor animEvtEditor, int frame) { FPlayAnimationEvent animEvt = (FPlayAnimationEvent)animEvtEditor._evt; if (animEvt._animationClip == null) { return; } bool isEditable = animEvt.IsAnimationEditable(); // render path if (isEditable) { TransformCurves transformCurves = new TransformCurves(animEvt.Owner, animEvt._animationClip); RenderTransformPath(transformCurves, animEvt.LengthTime, 1f / animEvt.Sequence.FrameRate); float t = (float)(frame + animEvt._startOffset - animEvt.Start) / animEvt.Sequence.FrameRate; if (animEvt.FrameRange.Contains(frame)) { // float t = (float)(frame + animEvt._startOffset - animEvt.Start) / animEvt.Sequence.FrameRate; RenderTransformAnimation(transformCurves, t); } // AnimationClipCurveData[] allCurves = AnimationUtility.GetAllCurves( animEvt._animationClip, true ); // foreach( AnimationClipCurveData curve in allCurves ) // { // // } } else if (animEvt.FrameRange.Contains(frame)) { float t = (float)(frame + animEvt._startOffset - animEvt.Start) / animEvt.Sequence.FrameRate; bool wasInAnimationMode = AnimationMode.InAnimationMode(); if (!AnimationMode.InAnimationMode()) { AnimationMode.StartAnimationMode(); } AnimationMode.BeginSampling(); AnimationMode.SampleAnimationClip(animEvt.Owner.gameObject, animEvt._animationClip, t); AnimationMode.EndSampling(); if (!wasInAnimationMode) { AnimationMode.StopAnimationMode(); } } }
public static void Resize(FEvent evt, FrameRange newFrameRange) { if (evt.FrameRange == newFrameRange || newFrameRange.Start > newFrameRange.End) { return; } if (newFrameRange.Length < evt.GetMinLength() || newFrameRange.Length > evt.GetMaxLength()) { Debug.LogError(string.Format("Trying to resize an Event to [{0},{1}] (length: {2}) which isn't a valid length, should be between [{3},{4}]", newFrameRange.Start, newFrameRange.End, newFrameRange.Length, evt.GetMinLength(), evt.GetMaxLength()), evt); return; } bool changedLength = evt.Length != newFrameRange.Length; if (!evt.GetTrack().CanAdd(evt, newFrameRange)) { return; } Undo.RecordObject(evt, changedLength ? "Resize Event" : "Move Event"); evt.Start = newFrameRange.Start; evt.End = newFrameRange.End; if (changedLength) { if (evt is FPlayAnimationEvent) { FPlayAnimationEvent animEvt = (FPlayAnimationEvent)evt; if (animEvt.IsAnimationEditable()) { FAnimationEventInspector.ScaleAnimationClip(animEvt._animationClip, animEvt.FrameRange); } } else if (evt is FTimescaleEvent) { ResizeAnimationCurve((FTimescaleEvent)evt, newFrameRange); } } EditorUtility.SetDirty(evt); if (FSequenceEditorWindow.instance != null) { FSequenceEditorWindow.instance.Repaint(); } }
private void OnUpdate() { if (!_syncWithAnimationWindow) { return; } if (Selection.activeTransform != Track.Owner) { Selection.activeTransform = Track.Owner; } if (!AnimationMode.InAnimationMode()) { // AnimationMode.StartAnimationMode(); AnimationWindowProxy.StartAnimationMode(); } // if( _track.IsPreviewing ) { int animWindowFrame = AnimationWindowProxy.GetCurrentFrame(); FEvent[] evts = new FEvent[2]; int numEvts = Track.GetEventsAt(SequenceEditor.Sequence.CurrentFrame, ref evts); if (numEvts > 0) { FPlayAnimationEvent animEvt = (FPlayAnimationEvent)evts[numEvts - 1]; if (animEvt.ControlsAnimation) { int normCurrentFrame = SequenceEditor.Sequence.CurrentFrame - animEvt.Start; if (animWindowFrame > animEvt.Length) { animWindowFrame = animEvt.Length; AnimationWindowProxy.SetCurrentFrame(animWindowFrame, animEvt.LengthTime); } if (animWindowFrame >= 0 && animWindowFrame != normCurrentFrame) { SequenceEditor.SetCurrentFrame(animEvt.Start + animWindowFrame); SequenceEditor.Repaint(); // Debug.Log( "AnimWindow->Flux: " + (animEvt.Start + animWindowFrame) ); } } } } }
protected override void OnEnable() { base.OnEnable(); if (target == null) { DestroyImmediate(this); return; } _animEvent = (FPlayAnimationEvent)target; _animationClip = serializedObject.FindProperty("_animationClip"); _startOffset = serializedObject.FindProperty("_startOffset"); _frameRange = serializedObject.FindProperty("_frameRange"); }
void OnSceneGUI(SceneView sceneView) { if (_track == null) { return; } for (int i = 0; i != _eventEditors.Count; ++i) { FAnimationEventEditor animEvtEditor = (FAnimationEventEditor)_eventEditors[i]; FPlayAnimationEvent animEvt = (FPlayAnimationEvent)_eventEditors[i]._evt; if (animEvt._animationClip != null && animEvt.IsAnimationEditable() && _track.IsPreviewing) { animEvtEditor.RenderTransformCurves(animEvt.Sequence.FrameRate); } } }
public override void UpdateEventsEditor(int frame, float time) { if (Track.RequiresEditorCache && Track.CanPreview && !Track.HasCache) { Track.CanPreview = false; OnTogglePreview(true); } base.UpdateEventsEditor(frame, time); FEvent[] evts = new FEvent[2]; int numEvts = Track.GetEventsAt(frame, ref evts); if (numEvts > 0) { // if( AnimationMode.InAnimationMode() ) if (_syncWithAnimationWindow) //&& _track.IsPreviewing ) { // Debug.Log( SequenceEditor.OnUpdateEvent ); // AnimationMode.StartAnimationMode(); // System.Type t = typeof(EditorWindow).Assembly.GetType("UnityEditor.AnimationWindow"); // EditorWindow animWindow = EditorWindow.GetWindow( t ); // // // PropertyInfo stateProperty = t.GetProperty("state", BindingFlags.Instance | BindingFlags.Public); // object state = stateProperty.GetValue( animWindow, null ); // // Type stateT = typeof(EditorWindow).Assembly.GetType("UnityEditorInternal.AnimationWindowState"); // FieldInfo timeField = stateT.GetField("m_PlayTime"); // timeField.SetValue( state, time ); // // FieldInfo frameField = stateT.GetField("m_Frame"); // frameField.SetValue( state, frame ); // if( !AnimationMode.InAnimationMode() ) // AnimationMode.StartAnimationMode(); FPlayAnimationEvent animEvt = (FPlayAnimationEvent)evts[numEvts - 1]; AnimationWindowProxy.SelectAnimationClip(animEvt._animationClip); AnimationWindowProxy.SetCurrentFrame(frame - animEvt.Start, time - animEvt.StartTime); // Debug.Log("Flux->AnimWindow: " + (frame - animEvt.Start)); } } }
public static UnityEditor.Animations.AnimatorTransition GetTransitionTo(FPlayAnimationEvent animEvt) { /* * FAnimationTrack animTrack = (FAnimationTrack)animEvt.GetTrack(); * * if( animTrack.GetAnimatorController() == null ) * return null; * * UnityEditor.Animations.AnimatorController controller = (UnityEditor.Animations.AnimatorController)animTrack.GetAnimatorController(); * * UnityEditor.Animations.AnimatorState animState = null; * * UnityEditor.Animations.AnimatorStateMachine stateMachine = controller.GetLayer(0).stateMachine; * * for( int i = 0; i != stateMachine.stateCount; ++i ) * { * if( stateMachine.GetState(i).uniqueNameHash == animEvt._stateHash ) * { * animState = stateMachine.GetState(i); * break; * } * } * * if( animState == null ) * { * // Debug.LogError("Couldn't find state " + animEvt._animationClip ); * return null; * } * * for( int i = 0; i != stateMachine.stateCount; ++i ) * { * UnityEditor.Animations.AnimatorState state = stateMachine.GetState(i); * UnityEditor.Animations.AnimatorTransition[] transitions = stateMachine.GetTransitionsFromState( state ); * for( int j = 0; j != transitions.Length; ++j ) * { * if( transitions[j].dstState == animState ) * { * return transitions[j]; * } * } * } */ return(null); }
void OnSceneGUI(SceneView sceneView) { if (Track == null) { return; } for (int i = 0; i != _eventEditors.Count; ++i) { FAnimationEventEditor animEvtEditor = (FAnimationEventEditor)_eventEditors[i]; FPlayAnimationEvent animEvt = (FPlayAnimationEvent)_eventEditors[i].Evt; if (animEvt._animationClip != null && Flux.FUtility.IsAnimationEditable(animEvt._animationClip) && ShowTransformPath /*_track.IsPreviewing*/) { animEvtEditor.RenderTransformCurves(animEvt.Sequence.FrameRate); } } SceneView.RepaintAll(); }
public override void Render(Rect rect, float headerWidth) { base.Render(rect, headerWidth); switch (Event.current.type) { case EventType.DragUpdated: if (rect.Contains(Event.current.mousePosition)) { int numAnimationsDragged = FAnimationEventInspector.NumAnimationsDragAndDrop(Track.Sequence.FrameRate); int frame = SequenceEditor.GetFrameForX(Event.current.mousePosition.x); DragAndDrop.visualMode = numAnimationsDragged > 0 && Track.CanAddAt(frame) ? DragAndDropVisualMode.Copy : DragAndDropVisualMode.Rejected; Event.current.Use(); } break; case EventType.DragPerform: if (rect.Contains(Event.current.mousePosition)) { AnimationClip animClip = FAnimationEventInspector.GetAnimationClipDragAndDrop(Track.Sequence.FrameRate); if (animClip && Mathf.Approximately(animClip.frameRate, Track.Sequence.FrameRate)) { int frame = SequenceEditor.GetFrameForX(Event.current.mousePosition.x); int maxLength; if (Track.CanAddAt(frame, out maxLength)) { FPlayAnimationEvent animEvt = FEvent.Create <FPlayAnimationEvent>(new FrameRange(frame, frame + Mathf.Min(maxLength, Mathf.RoundToInt(animClip.length * animClip.frameRate)))); Track.Add(animEvt); FAnimationEventInspector.SetAnimationClip(animEvt, animClip); DragAndDrop.AcceptDrag(); } } Event.current.Use(); } break; } }
protected override void OnEnable() { base.OnEnable(); if (target == null) { DestroyImmediate(this); return; } _animEvent = (FPlayAnimationEvent)target; _animationClip = serializedObject.FindProperty("_animationClip"); _startOffset = serializedObject.FindProperty("_startOffset"); _blendLength = serializedObject.FindProperty("_blendLength"); _frameRange = serializedObject.FindProperty("_frameRange"); _animationClipUI = new GUIContent("动画剪辑"); _frameRangeUI = new GUIContent("偏移+混合"); _startOffsetUI = new GUIContent("偏移帧数"); _blendLengthUI = new GUIContent("混合帧数"); }
// public static void Resize( FEvent evt, FrameRange newFrameRange ) // { // if( evt.FrameRange == newFrameRange || newFrameRange.Start > newFrameRange.End ) // return; // // if( newFrameRange.Length < evt.GetMinLength() || newFrameRange.Length > evt.GetMaxLength() ) // { // Debug.LogError( string.Format("Trying to resize an Event to [{0},{1}] (length: {2}) which isn't a valid length, should be between [{3},{4}]", newFrameRange.Start, newFrameRange.End, newFrameRange.Length, evt.GetMinLength(), evt.GetMaxLength() ), evt ); // return; // } // // bool changedLength = evt.Length != newFrameRange.Length; // // if( !evt.GetTrack().CanAdd( evt, newFrameRange ) ) // return; // // Undo.RecordObject( evt, changedLength ? "Resize Event" : "Move Event" ); // // evt.Start = newFrameRange.Start; // evt.End = newFrameRange.End; // // if( changedLength ) // { // if( evt is FPlayAnimationEvent ) // { // FPlayAnimationEvent animEvt = (FPlayAnimationEvent)evt; // // if( animEvt.IsAnimationEditable() ) // { // FAnimationEventInspector.ScaleAnimationClip( animEvt._animationClip, animEvt.FrameRange ); // } // } // else if( evt is FTimescaleEvent ) // { // ResizeAnimationCurve( (FTimescaleEvent)evt, newFrameRange ); // } // } // // EditorUtility.SetDirty( evt ); // // if( FSequenceEditorWindow.instance != null ) // FSequenceEditorWindow.instance.Repaint(); // } public static void Rescale(FEvent evt, FrameRange newFrameRange) { if (evt.FrameRange == newFrameRange) { return; } Undo.RecordObject(evt, string.Empty); evt.Start = newFrameRange.Start; evt.End = newFrameRange.End; if (evt is FPlayAnimationEvent) { FPlayAnimationEvent animEvt = (FPlayAnimationEvent)evt; if (animEvt._animationClip != null) { if (Flux.FUtility.IsAnimationEditable(animEvt._animationClip)) { animEvt._animationClip.frameRate = animEvt.Sequence.FrameRate; EditorUtility.SetDirty(animEvt._animationClip); } else if (Mathf.RoundToInt(animEvt._animationClip.frameRate) != animEvt.Sequence.FrameRate) { Debug.LogError(string.Format("Removed AnimationClip '{0}' ({1} fps) from Animation Event '{2}'", animEvt._animationClip.name, animEvt._animationClip.frameRate, animEvt.name), animEvt); animEvt._animationClip = null; } } } EditorUtility.SetDirty(evt); }
public static AnimationClip CreateAnimationClip(FPlayAnimationEvent animEvent) { string filePath = EditorUtility.SaveFilePanelInProject("Create Animation...", animEvent.Owner.name, "anim", "Choose path..."); if (string.IsNullOrEmpty(filePath)) { return(null); } AnimationClip clip = UnityEditor.Animations.AnimatorController.AllocateAnimatorClip(System.IO.Path.GetFileNameWithoutExtension(filePath)); clip.frameRate = animEvent.Sequence.FrameRate; Transform ownerTransform = animEvent.Owner; Vector3 pos = ownerTransform.localPosition; Quaternion rot = ownerTransform.localRotation; Keyframe[] xPosKeys = new Keyframe[] { new Keyframe(0, pos.x), new Keyframe(animEvent.LengthTime, pos.x) }; Keyframe[] yPosKeys = new Keyframe[] { new Keyframe(0, pos.y), new Keyframe(animEvent.LengthTime, pos.y) }; Keyframe[] zPosKeys = new Keyframe[] { new Keyframe(0, pos.z), new Keyframe(animEvent.LengthTime, pos.z) }; Keyframe[] xRotKeys = new Keyframe[] { new Keyframe(0, rot.x), new Keyframe(animEvent.LengthTime, rot.x) }; Keyframe[] yRotKeys = new Keyframe[] { new Keyframe(0, rot.y), new Keyframe(animEvent.LengthTime, rot.y) }; Keyframe[] zRotKeys = new Keyframe[] { new Keyframe(0, rot.z), new Keyframe(animEvent.LengthTime, rot.z) }; Keyframe[] wRotKeys = new Keyframe[] { new Keyframe(0, rot.w), new Keyframe(animEvent.LengthTime, rot.w) }; // set the tangent mode int tangentMode = 10; // 10 is unity auto tangent mode for (int i = 0; i != xPosKeys.Length; ++i) { xPosKeys[i].tangentMode = tangentMode; yPosKeys[i].tangentMode = tangentMode; zPosKeys[i].tangentMode = tangentMode; xRotKeys[i].tangentMode = tangentMode; yRotKeys[i].tangentMode = tangentMode; zRotKeys[i].tangentMode = tangentMode; wRotKeys[i].tangentMode = tangentMode; } AnimationCurve xPos = new AnimationCurve(xPosKeys); AnimationCurve yPos = new AnimationCurve(yPosKeys); AnimationCurve zPos = new AnimationCurve(zPosKeys); AnimationCurve xRot = new AnimationCurve(xRotKeys); AnimationCurve yRot = new AnimationCurve(yRotKeys); AnimationCurve zRot = new AnimationCurve(zRotKeys); AnimationCurve wRot = new AnimationCurve(wRotKeys); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalPosition.x"), xPos); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalPosition.y"), yPos); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalPosition.z"), zPos); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalRotation.x"), xRot); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalRotation.y"), yRot); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalRotation.z"), zRot); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalRotation.w"), wRot); clip.EnsureQuaternionContinuity(); AssetDatabase.CreateAsset(clip, filePath); FAnimationEventInspector.SetAnimationClip(animEvent, clip); return(clip); }
private void UpdateEventFromController() { bool isBlending = AnimEvt.IsBlending(); if (isBlending) { if (_transitionToState == null) { _transitionToState = FAnimationTrackInspector.GetTransitionTo(AnimEvt); if (_transitionToState == null || _transitionToState.conditions.Length > 0) { FAnimationTrackInspector.RebuildStateMachine((FAnimationTrack)TrackEditor.Track); _transitionToState = FAnimationTrackInspector.GetTransitionTo(AnimEvt); } } if (_transitionSO == null) { if (_transitionToState != null) { _transitionSO = new SerializedObject(_transitionToState); _transitionExitTime = _transitionSO.FindProperty("m_ExitTime"); _transitionDuration = _transitionSO.FindProperty("m_TransitionDuration"); _transitionOffset = _transitionSO.FindProperty("m_TransitionOffset"); } } else if (_transitionSO.targetObject == null) { _transitionExitTime = null; _transitionDuration = null; _transitionOffset = null; _transitionSO = null; } } else { if (_transitionToState != null || _transitionSO != null) { _transitionToState = null; _transitionSO = null; _transitionExitTime = null; _transitionOffset = null; _transitionDuration = null; } } if (_transitionSO != null) { _transitionSO.Update(); _animEvtSO.Update(); FPlayAnimationEvent prevAnimEvt = (FPlayAnimationEvent)AnimTrack.Events[AnimEvt.GetId() - 1]; AnimationClip prevAnimEvtClip = prevAnimEvt._animationClip; if (prevAnimEvtClip != null) { float blendSeconds = _blendLength.intValue / prevAnimEvtClip.frameRate; if (!Mathf.Approximately(blendSeconds, _transitionDuration.floatValue)) { _transitionDuration.floatValue = blendSeconds; float p = blendSeconds / prevAnimEvtClip.length; _transitionExitTime.floatValue = p > 1f ? 1f : 1f - Mathf.Clamp01(blendSeconds / prevAnimEvtClip.length); _animEvtSO.ApplyModifiedProperties(); } float startOffsetNorm = _startOffset.intValue / AnimEvt._animationClip.frameRate / AnimEvt._animationClip.length; if (!Mathf.Approximately(startOffsetNorm, _transitionOffset.floatValue)) { _transitionOffset.floatValue = startOffsetNorm; _animEvtSO.ApplyModifiedProperties(); } } _transitionSO.ApplyModifiedProperties(); } }
protected override void RenderEvent(FrameRange viewRange, FrameRange validKeyframeRange) { if (_animEvtSO == null) { _animEvtSO = new SerializedObject(AnimEvt); _blendLength = _animEvtSO.FindProperty("_blendLength"); _startOffset = _animEvtSO.FindProperty("_startOffset"); } UpdateEventFromController(); _animEvtSO.Update(); FAnimationTrackEditor animTrackEditor = (FAnimationTrackEditor)TrackEditor; Rect transitionOffsetRect = _eventRect; int startOffsetHandleId = EditorGUIUtility.GetControlID(FocusType.Passive); int transitionHandleId = EditorGUIUtility.GetControlID(FocusType.Passive); bool isBlending = AnimEvt.IsBlending(); bool isAnimEditable = Flux.FUtility.IsAnimationEditable(AnimEvt._animationClip); if (isBlending) { transitionOffsetRect.xMin = Rect.xMin + SequenceEditor.GetXForFrame(AnimEvt.Start + AnimEvt._blendLength) - 3; transitionOffsetRect.width = 6; transitionOffsetRect.yMin = transitionOffsetRect.yMax - 8; } switch (Event.current.type) { case EventType.MouseDown: if (EditorGUIUtility.hotControl == 0 && Event.current.alt && !isAnimEditable) { if (isBlending && transitionOffsetRect.Contains(Event.current.mousePosition)) { EditorGUIUtility.hotControl = transitionHandleId; AnimatorWindowProxy.OpenAnimatorWindowWithAnimatorController((AnimatorController)AnimTrack.AnimatorController); if (Selection.activeObject != _transitionToState) { Selection.activeObject = _transitionToState; } Event.current.Use(); } else if (_eventRect.Contains(Event.current.mousePosition)) { _mouseDown = SequenceEditor.GetFrameForX(Event.current.mousePosition.x) - AnimEvt.Start; EditorGUIUtility.hotControl = startOffsetHandleId; Event.current.Use(); } } break; case EventType.Ignore: case EventType.MouseUp: if (EditorGUIUtility.hotControl == transitionHandleId || EditorGUIUtility.hotControl == startOffsetHandleId) { EditorGUIUtility.hotControl = 0; Event.current.Use(); } break; case EventType.MouseDrag: if (EditorGUIUtility.hotControl == transitionHandleId) { int mouseDragPos = Mathf.Clamp(SequenceEditor.GetFrameForX(Event.current.mousePosition.x - Rect.x) - AnimEvt.Start, 0, AnimEvt.Length); if (_blendLength.intValue != mouseDragPos) { _blendLength.intValue = mouseDragPos; FPlayAnimationEvent prevAnimEvt = (FPlayAnimationEvent)animTrackEditor.Track.GetEvent(AnimEvt.GetId() - 1); if (_transitionDuration != null) { _transitionDuration.floatValue = (_blendLength.intValue / prevAnimEvt._animationClip.frameRate) / prevAnimEvt._animationClip.length; } Undo.RecordObject(this, "Animation Blending"); } Event.current.Use(); } else if (EditorGUIUtility.hotControl == startOffsetHandleId) { int mouseDragPos = Mathf.Clamp(SequenceEditor.GetFrameForX(Event.current.mousePosition.x - Rect.x) - AnimEvt.Start, 0, AnimEvt.Length); int delta = _mouseDown - mouseDragPos; _mouseDown = mouseDragPos; _startOffset.intValue = Mathf.Clamp(_startOffset.intValue + delta, 0, AnimEvt._animationClip.isLooping ? AnimEvt.Length : Mathf.RoundToInt(AnimEvt._animationClip.length * AnimEvt._animationClip.frameRate) - AnimEvt.Length); if (_transitionOffset != null) { _transitionOffset.floatValue = (_startOffset.intValue / AnimEvt._animationClip.frameRate) / AnimEvt._animationClip.length; } Undo.RecordObject(this, "Animation Offset"); Event.current.Use(); } break; } _animEvtSO.ApplyModifiedProperties(); if (_transitionSO != null) { _transitionSO.ApplyModifiedProperties(); } switch (Event.current.type) { case EventType.DragUpdated: if (_eventRect.Contains(Event.current.mousePosition)) { int numAnimationsDragged = FAnimationEventInspector.NumAnimationsDragAndDrop(Evt.Sequence.FrameRate); DragAndDrop.visualMode = numAnimationsDragged > 0 ? DragAndDropVisualMode.Link : DragAndDropVisualMode.Rejected; Event.current.Use(); } break; case EventType.DragPerform: if (_eventRect.Contains(Event.current.mousePosition)) { AnimationClip animationClipDragged = FAnimationEventInspector.GetAnimationClipDragAndDrop(Evt.Sequence.FrameRate); if (animationClipDragged) { int animFrameLength = Mathf.RoundToInt(animationClipDragged.length * animationClipDragged.frameRate); FAnimationEventInspector.SetAnimationClip(AnimEvt, animationClipDragged); FrameRange maxRange = AnimEvt.GetMaxFrameRange(); SequenceEditor.MoveEvent(AnimEvt, new FrameRange(AnimEvt.Start, Mathf.Min(AnimEvt.Start + animFrameLength, maxRange.End))); DragAndDrop.AcceptDrag(); Event.current.Use(); } else { Event.current.Use(); } } break; } // FrameRange currentRange = Evt.FrameRange; base.RenderEvent(viewRange, validKeyframeRange); // if( isAnimEditable && currentRange.Length != Evt.FrameRange.Length ) // { // FAnimationEventInspector.ScaleAnimationClip( AnimEvt._animationClip, Evt.FrameRange ); // } if (Event.current.type == EventType.Repaint) { if (isBlending && !isAnimEditable && viewRange.Contains(AnimEvt.Start + AnimEvt._blendLength)) { GUISkin skin = FUtility.GetFluxSkin(); GUIStyle transitionOffsetStyle = skin.GetStyle("BlendOffset"); Texture2D t = FUtility.GetFluxTexture("EventBlend.png"); Rect r = new Rect(_eventRect.xMin, _eventRect.yMin + 1, transitionOffsetRect.center.x - _eventRect.xMin, _eventRect.height - 2); Color guiColor = GUI.color; Color c = new Color(1f, 1f, 1f, 0.3f); c.a *= guiColor.a; GUI.color = c; GUI.DrawTexture(r, t); if (Event.current.alt) { GUI.color = Color.white; } transitionOffsetStyle.Draw(transitionOffsetRect, false, false, false, false); GUI.color = guiColor; // Debug.Log ( transitionOffsetRect ); } // GUI.color = Color.red; if (EditorGUIUtility.hotControl == transitionHandleId) { Rect transitionOffsetTextRect = transitionOffsetRect; transitionOffsetTextRect.y -= 16; transitionOffsetTextRect.height = 20; transitionOffsetTextRect.width += 50; GUI.Label(transitionOffsetTextRect, AnimEvt._blendLength.ToString(), EditorStyles.label); } if (EditorGUIUtility.hotControl == startOffsetHandleId) { Rect startOffsetTextRect = _eventRect; GUI.Label(startOffsetTextRect, AnimEvt._startOffset.ToString(), EditorStyles.label); } } }
public static AnimationClip CreateAnimationClip(FPlayAnimationEvent animEvent) { FAnimationTrack track = (FAnimationTrack)animEvent.Track; string animName = ((FAnimationTrack)animEvent.Track).LayerName + "_" + animEvent.GetId().ToString(); AnimationClip clip = AnimatorController.AllocateAnimatorClip(animName); clip.frameRate = animEvent.Sequence.FrameRate; Transform ownerTransform = animEvent.Owner; Vector3 pos = ownerTransform.localPosition; Vector3 rot = ownerTransform.localRotation.eulerAngles; //ownerTransform.localEulerAngles; Keyframe[] xPosKeys = new Keyframe[] { new Keyframe(0, pos.x), new Keyframe(animEvent.LengthTime, pos.x) }; Keyframe[] yPosKeys = new Keyframe[] { new Keyframe(0, pos.y), new Keyframe(animEvent.LengthTime, pos.y) }; Keyframe[] zPosKeys = new Keyframe[] { new Keyframe(0, pos.z), new Keyframe(animEvent.LengthTime, pos.z) }; Keyframe[] xRotKeys = new Keyframe[] { new Keyframe(0, rot.x), new Keyframe(animEvent.LengthTime, rot.x) }; Keyframe[] yRotKeys = new Keyframe[] { new Keyframe(0, rot.y), new Keyframe(animEvent.LengthTime, rot.y) }; Keyframe[] zRotKeys = new Keyframe[] { new Keyframe(0, rot.z), new Keyframe(animEvent.LengthTime, rot.z) }; // set the tangent mode int tangentMode = 10; // 10 is unity auto tangent mode for (int i = 0; i != xPosKeys.Length; ++i) { xPosKeys[i].tangentMode = tangentMode; yPosKeys[i].tangentMode = tangentMode; zPosKeys[i].tangentMode = tangentMode; xRotKeys[i].tangentMode = tangentMode; yRotKeys[i].tangentMode = tangentMode; zRotKeys[i].tangentMode = tangentMode; } AnimationCurve xPos = new AnimationCurve(xPosKeys); AnimationCurve yPos = new AnimationCurve(yPosKeys); AnimationCurve zPos = new AnimationCurve(zPosKeys); AnimationCurve xRot = new AnimationCurve(xRotKeys); AnimationCurve yRot = new AnimationCurve(yRotKeys); AnimationCurve zRot = new AnimationCurve(zRotKeys); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalPosition.x"), xPos); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalPosition.y"), yPos); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalPosition.z"), zPos); // workaround unity bug of spilling errors if you just set localEulerAngles Quaternion quat = ownerTransform.localRotation; Keyframe[] xQuatKeys = new Keyframe[] { new Keyframe(0, quat.x), new Keyframe(animEvent.LengthTime, quat.x) }; Keyframe[] yQuatKeys = new Keyframe[] { new Keyframe(0, quat.y), new Keyframe(animEvent.LengthTime, quat.y) }; Keyframe[] zQuatKeys = new Keyframe[] { new Keyframe(0, quat.z), new Keyframe(animEvent.LengthTime, quat.z) }; Keyframe[] wQuatKeys = new Keyframe[] { new Keyframe(0, quat.w), new Keyframe(animEvent.LengthTime, quat.w) }; AnimationCurve xQuat = new AnimationCurve(xQuatKeys); AnimationCurve yQuat = new AnimationCurve(yQuatKeys); AnimationCurve zQuat = new AnimationCurve(zQuatKeys); AnimationCurve wQuat = new AnimationCurve(wQuatKeys); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalRotation.x"), xQuat); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalRotation.y"), yQuat); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalRotation.z"), zQuat); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "m_LocalRotation.w"), wQuat); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "localEulerAngles.x"), xRot); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "localEulerAngles.y"), yRot); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(string.Empty, typeof(Transform), "localEulerAngles.z"), zRot); clip.EnsureQuaternionContinuity(); AssetDatabase.AddObjectToAsset(clip, track.AnimatorController); AnimationClipSettings clipSettings = AnimationUtility.GetAnimationClipSettings(clip); clipSettings.loopTime = false; AnimationUtility.SetAnimationClipSettings(clip, clipSettings); AssetDatabase.SaveAssets(); FAnimationEventInspector.SetAnimationClip(animEvent, clip); return(clip); }
// protected override void OnEnable() // { // base.OnEnable(); // } // // protected override void OnDestroy() // { // base.OnDestroy(); // } // protected override void Init( FObject obj ) // { // base.Init( obj, ); // // _animEvt = (FPlayAnimationEvent)_evt; // // _animTrack = (FAnimationTrack)_animEvt.GetTrack(); // // // } 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 || _transitionToState.conditions.Length > 0) { // if( animTrackEditor.PreviewInSceneView ) // animTrackEditor.ClearPreview(); FAnimationTrackInspector.RebuildStateMachine((FAnimationTrack)TrackEditor.Track); _transitionToState = FAnimationTrackInspector.GetTransitionTo(AnimEvt); } } // else // { // if( _transitionToState.conditions.Length > 0 ) // { // FAnimationTrackInspector.RebuildStateMachine( (FAnimationTrack)_trackEditor._track ); // } // } if (_transitionSO == null) { if (_transitionToState != null) { _transitionSO = new SerializedObject(_transitionToState); // SerializedProperty p = _transitionSO.GetIterator(); // // while( p.Next( true ) ) // Debug.Log (p.propertyPath ); _transitionExitTime = _transitionSO.FindProperty("m_ExitTime"); _transitionDuration = _transitionSO.FindProperty("m_TransitionDuration"); _transitionOffset = _transitionSO.FindProperty("m_TransitionOffset"); } } else if (_transitionSO.targetObject == null) { _transitionExitTime = null; _transitionDuration = null; _transitionOffset = null; _transitionSO = null; } } else { if (_transitionToState != null || _transitionSO != null) { _transitionToState = null; _transitionSO = null; _transitionExitTime = null; _transitionOffset = null; _transitionDuration = null; } } if (_transitionSO != null) { _transitionSO.Update(); _animEvtSO.Update(); FPlayAnimationEvent prevAnimEvt = (FPlayAnimationEvent)AnimTrack.Events[AnimEvt.GetId() - 1]; AnimationClip prevAnimEvtClip = prevAnimEvt._animationClip; if (prevAnimEvtClip != null) { float exitTimeNormalized = (prevAnimEvt.Length + prevAnimEvt._startOffset) / (prevAnimEvtClip.frameRate * prevAnimEvtClip.length); if (!Mathf.Approximately(exitTimeNormalized, _transitionExitTime.floatValue)) { _transitionExitTime.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(); } float startOffsetNorm = (_startOffset.intValue / AnimEvt._animationClip.frameRate) / AnimEvt._animationClip.length; if (!Mathf.Approximately(startOffsetNorm, _transitionOffset.floatValue)) { _startOffset.intValue = Mathf.RoundToInt(_transitionOffset.floatValue * AnimEvt._animationClip.length * AnimEvt._animationClip.frameRate); _transitionOffset.floatValue = (_startOffset.intValue / AnimEvt._animationClip.frameRate) / AnimEvt._animationClip.length; _animEvtSO.ApplyModifiedProperties(); } } _transitionSO.ApplyModifiedProperties(); } }
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); } }
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(); } }