diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index 3d91d87b3..b5ae35cd0 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -1448,6 +1448,12 @@ namespace FlaxEditor [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool Internal_CanSetToRoot(IntPtr prefab, IntPtr newRoot); + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern float Internal_GetAnimationTime(IntPtr animatedModel); + + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern void Internal_SetAnimationTime(IntPtr animatedModel, float time); + #endregion } } diff --git a/Source/Editor/GUI/Timeline/AnimationTimeline.cs b/Source/Editor/GUI/Timeline/AnimationTimeline.cs index 16b5a0b21..ffc06d5d6 100644 --- a/Source/Editor/GUI/Timeline/AnimationTimeline.cs +++ b/Source/Editor/GUI/Timeline/AnimationTimeline.cs @@ -4,6 +4,7 @@ using System; using FlaxEditor.GUI.Timeline.Tracks; using FlaxEditor.Viewport.Previews; using FlaxEngine; +using Object = FlaxEngine.Object; namespace FlaxEditor.GUI.Timeline { @@ -101,6 +102,8 @@ namespace FlaxEditor.GUI.Timeline { state = PlaybackStates.Paused; } + var time = Editor.Internal_GetAnimationTime(Object.GetUnmanagedPtr(_preview.PreviewActor)); + CurrentFrame = (int)(time * FramesPerSecond); } else { @@ -120,7 +123,12 @@ namespace FlaxEditor.GUI.Timeline /// public override void OnPlay() { + var time = CurrentTime; _preview.Play(); + if (_preview != null) + { + Editor.Internal_SetAnimationTime(Object.GetUnmanagedPtr(_preview.PreviewActor), time); + } base.OnPlay(); } @@ -144,7 +152,17 @@ namespace FlaxEditor.GUI.Timeline /// public override void OnSeek(int frame) { - CurrentFrame = frame; + if (_preview != null) + { + var time = frame / FramesPerSecond; + Editor.Internal_SetAnimationTime(Object.GetUnmanagedPtr(_preview.PreviewActor), time); + if (!_preview.PlayAnimation) + _preview.PreviewActor.UpdateAnimation(); + } + else + { + CurrentFrame = frame; + } base.OnSeek(frame); } diff --git a/Source/Editor/Managed/ManagedEditor.Internal.cpp b/Source/Editor/Managed/ManagedEditor.Internal.cpp index 16d962cba..8fff3f2f8 100644 --- a/Source/Editor/Managed/ManagedEditor.Internal.cpp +++ b/Source/Editor/Managed/ManagedEditor.Internal.cpp @@ -44,6 +44,7 @@ #include "Engine/Input/Keyboard.h" #include "Engine/Threading/Threading.h" #include "FlaxEngine.Gen.h" +#include "Engine/Level/Actors/AnimatedModel.h" #include "Engine/Serialization/JsonTools.h" #include @@ -1064,6 +1065,17 @@ public: return true; } + static float GetAnimationTime(AnimatedModel* animatedModel) + { + return animatedModel && animatedModel->GraphInstance.State.Count() == 1 ? animatedModel->GraphInstance.State[0].Animation.TimePosition : 0.0f; + } + + static void SetAnimationTime(AnimatedModel* animatedModel, float time) + { + if (animatedModel && animatedModel->GraphInstance.State.Count() == 1) + animatedModel->GraphInstance.State[0].Animation.TimePosition = time; + } + static void InitRuntime() { ADD_INTERNAL_CALL("FlaxEditor.Editor::IsDevInstance", &IsDevInstance); @@ -1111,6 +1123,8 @@ public: ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_DeserializeSceneObject", &DeserializeSceneObject); ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_LoadAsset", &LoadAsset); ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_CanSetToRoot", &CanSetToRoot); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_GetAnimationTime", &GetAnimationTime); + ADD_INTERNAL_CALL("FlaxEditor.Editor::Internal_SetAnimationTime", &SetAnimationTime); } };