From 37032301f1c6d594a2d1ba0ec91e2c371305ecdf Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 18:29:47 +0900 Subject: [PATCH 01/11] Change: elapsed time calculation method --- .../Editor/EditorUpdateMotionScheduler.cs | 6 +- .../LitMotion/Runtime/IMotionScheduler.cs | 12 ++++ .../LitMotion/Runtime/Internal/MotionData.cs | 2 +- .../Runtime/Internal/UpdateRunner.cs | 8 +-- .../Runtime/ManualMotionDispatcher.cs | 19 ++++- .../Assets/LitMotion/Runtime/MotionBuilder.cs | 1 + .../LitMotion/Runtime/MotionDispatcher.cs | 70 +++++++++++-------- .../LitMotion/Runtime/MotionUpdateJob.cs | 21 +++--- .../Schedulers/FixedUpdateMotionScheduler.cs | 21 ------ .../FixedUpdateMotionScheduler.cs.meta | 11 --- .../Schedulers/LateUpdateMotionScheduler.cs | 21 ------ .../LateUpdateMotionScheduler.cs.meta | 11 --- .../Schedulers/ManualMotionScheduler.cs | 2 + .../Runtime/Schedulers/MotionScheduler.cs | 6 +- .../Schedulers/PlayerLoopMotionScheduler.cs | 64 +++++++++++++++++ ...meta => PlayerLoopMotionScheduler.cs.meta} | 2 +- .../Schedulers/UpdateMotionScheduler.cs | 21 ------ 17 files changed, 159 insertions(+), 139 deletions(-) delete mode 100644 src/LitMotion/Assets/LitMotion/Runtime/Schedulers/FixedUpdateMotionScheduler.cs delete mode 100644 src/LitMotion/Assets/LitMotion/Runtime/Schedulers/FixedUpdateMotionScheduler.cs.meta delete mode 100644 src/LitMotion/Assets/LitMotion/Runtime/Schedulers/LateUpdateMotionScheduler.cs delete mode 100644 src/LitMotion/Assets/LitMotion/Runtime/Schedulers/LateUpdateMotionScheduler.cs.meta create mode 100644 src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs rename src/LitMotion/Assets/LitMotion/Runtime/Schedulers/{UpdateMotionScheduler.cs.meta => PlayerLoopMotionScheduler.cs.meta} (83%) delete mode 100644 src/LitMotion/Assets/LitMotion/Runtime/Schedulers/UpdateMotionScheduler.cs diff --git a/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs index 62cc5210..70c4a4c7 100644 --- a/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs @@ -1,13 +1,17 @@ +using UnityEditor; + namespace LitMotion.Editor { internal sealed class EditorUpdateMotionScheduler : IMotionScheduler { + public double Time => EditorApplication.timeSinceStartup; + public MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) where TValue : unmanaged where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter { - return MotionDispatcher.Schedule(data, callbackData, UpdateMode.EditorApplicationUpdate); + return MotionDispatcher.ScheduleOnEditor(data, callbackData); } } } \ No newline at end of file diff --git a/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs index 91a8ce73..a03b0301 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs @@ -18,5 +18,17 @@ MotionHandle Schedule(in MotionData; + + /// + /// Returns the current time. + /// + double Time { get; } + } + + internal enum TimeKind + { + Time, + UnscaledTime, + Realtime } } \ No newline at end of file diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Internal/MotionData.cs b/src/LitMotion/Assets/LitMotion/Runtime/Internal/MotionData.cs index 25a20f6e..18d58a85 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Internal/MotionData.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Internal/MotionData.cs @@ -14,7 +14,7 @@ public struct MotionData { public MotionStatus Status; - public float Time; + public double StartTime; public float Duration; public Ease Ease; diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Internal/UpdateRunner.cs b/src/LitMotion/Assets/LitMotion/Runtime/Internal/UpdateRunner.cs index a1105ca5..dfd0baf8 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Internal/UpdateRunner.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Internal/UpdateRunner.cs @@ -8,7 +8,7 @@ namespace LitMotion { internal interface IUpdateRunner { - public void Update(float deltaTime, float unscaledDeltaTime); + public void Update(double time, double unscaledTime); public void Reset(); } @@ -24,7 +24,7 @@ public UpdateRunner(MotionStorage storage) readonly MotionStorage storage; - public unsafe void Update(float deltaTime, float unscaledDeltaTime) + public unsafe void Update(double time, double unscaledTime) { var count = storage.Count; using var output = new NativeArray(count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); @@ -36,8 +36,8 @@ public unsafe void Update(float deltaTime, float unscaledDeltaTime) var job = new MotionUpdateJob() { DataPtr = dataPtr, - DeltaTime = deltaTime, - UnscaledDeltaTime = unscaledDeltaTime, + Time = time, + UnscaledTime = unscaledTime, Output = output, CompletedIndexList = completedIndexList.AsParallelWriter() }; diff --git a/src/LitMotion/Assets/LitMotion/Runtime/ManualMotionDispatcher.cs b/src/LitMotion/Assets/LitMotion/Runtime/ManualMotionDispatcher.cs index b6397eac..04b521ec 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/ManualMotionDispatcher.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/ManualMotionDispatcher.cs @@ -29,6 +29,11 @@ public static MotionStorage GetOrCreate() static readonly MinimumList updateRunners = new(); + /// + /// ManualMotionDispatcher time. It increases every time Update is called. + /// + public static double Time { get; set; } + /// /// Ensures the storage capacity until it reaches at least `capacity`. /// @@ -45,14 +50,22 @@ public static void EnsureStorageCapacity(int capacit /// Update all scheduled motions with MotionScheduler.Manual /// /// Delta time - public static void Update(float deltaTime) + public static void Update(double deltaTime) { if (deltaTime < 0f) throw new ArgumentException("deltaTime must be 0 or higher."); - + Time += deltaTime; + Update(); + } + + /// + /// Update all scheduled motions with MotionScheduler.Manual + /// + public static void Update() + { var span = updateRunners.AsSpan(); for (int i = 0; i < span.Length; i++) { - span[i].Update(deltaTime, deltaTime); + span[i].Update(Time, Time); } } diff --git a/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs b/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs index 7431b66a..7de69924 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs @@ -335,6 +335,7 @@ internal MotionData BuildMotionData() StartValue = buffer.StartValue, EndValue = buffer.EndValue, Options = buffer.Options, + StartTime = buffer.Scheduler == null ? MotionScheduler.Update.Time : buffer.Scheduler.Time, Duration = buffer.Duration, Ease = buffer.Ease, IgnoreTimeScale = buffer.IgnoreTimeScale, diff --git a/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs b/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs index 2c3d1a26..99650e2b 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs @@ -9,14 +9,11 @@ internal enum UpdateMode { Update = 0, LateUpdate = 1, - FixedUpdate = 2, -#if UNITY_EDITOR - EditorApplicationUpdate = 10 -#endif + FixedUpdate = 2 } /// - /// Motion dispatcher for Runtime. + /// Motion dispatcher. /// [DisallowMultipleComponent] [AddComponentMenu("")] @@ -66,18 +63,21 @@ public static MotionStorage GetOrCreate(UpdateMode u fixedUpdate = storage; } return fixedUpdate; + } + } + #if UNITY_EDITOR - case UpdateMode.EditorApplicationUpdate: - if (editorApplicationUpdate == null) - { - var storage = new MotionStorage(MotionStorageManager.CurrentStorageId); - MotionStorageManager.AddStorage(storage); - editorApplicationUpdate = storage; - } - return editorApplicationUpdate; -#endif + public static MotionStorage GetOrCreateEditor() + { + if (editorApplicationUpdate == null) + { + var storage = new MotionStorage(MotionStorageManager.CurrentStorageId); + MotionStorageManager.AddStorage(storage); + editorApplicationUpdate = storage; } + return editorApplicationUpdate; } +#endif } static class RunnerCache @@ -113,7 +113,7 @@ public static void EnsureStorageCapacity(int capacit StorageCache.GetOrCreate(UpdateMode.LateUpdate).EnsureCapacity(capacity); StorageCache.GetOrCreate(UpdateMode.FixedUpdate).EnsureCapacity(capacity); #if UNITY_EDITOR - StorageCache.GetOrCreate(UpdateMode.EditorApplicationUpdate).EnsureCapacity(capacity); + StorageCache.GetOrCreateEditor().EnsureCapacity(capacity); #endif } @@ -122,7 +122,7 @@ internal static MotionHandle Schedule(in MotionData< where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter { - MotionStorage storage = StorageCache.GetOrCreate(updateMode); + var storage = StorageCache.GetOrCreate(updateMode); switch (updateMode) { default: @@ -150,16 +150,6 @@ internal static MotionHandle Schedule(in MotionData< RunnerCache.fixedUpdate = runner; } break; -#if UNITY_EDITOR - case UpdateMode.EditorApplicationUpdate: - if (RunnerCache.editorApplicationUpdate == null) - { - var runner = new UpdateRunner(storage); - editorApplicationUpdateRunners.Add(runner); - RunnerCache.editorApplicationUpdate = runner; - } - break; -#endif } var (EntryIndex, Version) = storage.Append(data, callbackData); @@ -181,19 +171,19 @@ static void Init() void Update() { var span = updateRunners.AsSpan(); - for (int i = 0; i < span.Length; i++) span[i].Update(Time.deltaTime, Time.unscaledDeltaTime); + for (int i = 0; i < span.Length; i++) span[i].Update(Time.timeAsDouble, Time.unscaledTimeAsDouble); } void LateUpdate() { var span = lateUpdateRunners.AsSpan(); - for (int i = 0; i < span.Length; i++) span[i].Update(Time.deltaTime, Time.unscaledDeltaTime); + for (int i = 0; i < span.Length; i++) span[i].Update(Time.timeAsDouble, Time.unscaledTimeAsDouble); } void FixedUpdate() { var span = fixedUpdateRunners.AsSpan(); - for (int i = 0; i < span.Length; i++) span[i].Update(Time.fixedDeltaTime, Time.fixedUnscaledDeltaTime); + for (int i = 0; i < span.Length; i++) span[i].Update(Time.fixedTime, Time.fixedTimeAsDouble); } void OnDestroy() @@ -215,6 +205,28 @@ void ResetAll(MinimumList list) #if UNITY_EDITOR static double lastEditorTime; + internal static MotionHandle ScheduleOnEditor(in MotionData data, in MotionCallbackData callbackData) + where TValue : unmanaged + where TOptions : unmanaged, IMotionOptions + where TAdapter : unmanaged, IMotionAdapter + { + var storage = StorageCache.GetOrCreateEditor(); + if (RunnerCache.editorApplicationUpdate == null) + { + var runner = new UpdateRunner(storage); + editorApplicationUpdateRunners.Add(runner); + RunnerCache.editorApplicationUpdate = runner; + } + + var (EntryIndex, Version) = storage.Append(data, callbackData); + return new MotionHandle() + { + StorageId = storage.StorageId, + Index = EntryIndex, + Version = Version + }; + } + [InitializeOnLoadMethod] static void InitEditor() { diff --git a/src/LitMotion/Assets/LitMotion/Runtime/MotionUpdateJob.cs b/src/LitMotion/Assets/LitMotion/Runtime/MotionUpdateJob.cs index 70895f81..e3958efb 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/MotionUpdateJob.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/MotionUpdateJob.cs @@ -20,25 +20,22 @@ public unsafe struct MotionUpdateJob : IJobParallelF where TAdapter : unmanaged, IMotionAdapter { [NativeDisableUnsafePtrRestriction] public MotionData* DataPtr; - [ReadOnly] public float DeltaTime; - [ReadOnly] public float UnscaledDeltaTime; + [ReadOnly] public double Time; + [ReadOnly] public double UnscaledTime; [WriteOnly] public NativeList.ParallelWriter CompletedIndexList; [WriteOnly] public NativeArray Output; public void Execute([AssumeRange(0, int.MaxValue)] int index) { - Hint.Assume(DeltaTime >= 0f); - Hint.Assume(UnscaledDeltaTime >= 0f); - var ptr = DataPtr + index; if (Hint.Likely(ptr->Status is MotionStatus.Scheduled or MotionStatus.Delayed or MotionStatus.Playing)) { - ptr->Time += ptr->IgnoreTimeScale ? UnscaledDeltaTime : DeltaTime; - var time = ptr->Time - ptr->Delay; + var motionTime = (ptr->IgnoreTimeScale ? UnscaledTime : Time) - ptr->StartTime; + var time = motionTime - ptr->Delay; - float t; + double t; bool isCompleted; int completedLoops; int clampedCompletedLoops; @@ -80,14 +77,14 @@ public void Execute([AssumeRange(0, int.MaxValue)] int index) { default: case LoopType.Restart: - progress = EaseUtility.Evaluate(t, ptr->Ease); + progress = EaseUtility.Evaluate((float)t, ptr->Ease); break; case LoopType.Yoyo: - progress = EaseUtility.Evaluate(t, ptr->Ease); + progress = EaseUtility.Evaluate((float)t, ptr->Ease); if ((clampedCompletedLoops + (int)t) % 2 == 1) progress = 1f - progress; break; case LoopType.Incremental: - progress = EaseUtility.Evaluate(1f, ptr->Ease) * clampedCompletedLoops + EaseUtility.Evaluate(math.fmod(t, 1f), ptr->Ease); + progress = EaseUtility.Evaluate(1f, ptr->Ease) * clampedCompletedLoops + EaseUtility.Evaluate((float)math.fmod(t, 1f), ptr->Ease); break; } @@ -95,7 +92,7 @@ public void Execute([AssumeRange(0, int.MaxValue)] int index) { ptr->Status = MotionStatus.Completed; } - else if (ptr->Time < ptr->Delay) + else if (motionTime < ptr->Delay) { ptr->Status = MotionStatus.Delayed; } diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/FixedUpdateMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/FixedUpdateMotionScheduler.cs deleted file mode 100644 index 566387f1..00000000 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/FixedUpdateMotionScheduler.cs +++ /dev/null @@ -1,21 +0,0 @@ -using UnityEngine; - -namespace LitMotion -{ - internal sealed class FixedUpdateMotionScheduler : IMotionScheduler - { - public MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) - where TValue : unmanaged - where TOptions : unmanaged, IMotionOptions - where TAdapter : unmanaged, IMotionAdapter - { -#if UNITY_EDITOR - if (!Application.isPlaying) - { - MotionDispatcher.Schedule(data, callbackData, UpdateMode.EditorApplicationUpdate); - } -#endif - return MotionDispatcher.Schedule(data, callbackData, UpdateMode.FixedUpdate); - } - } -} \ No newline at end of file diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/FixedUpdateMotionScheduler.cs.meta b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/FixedUpdateMotionScheduler.cs.meta deleted file mode 100644 index d4a59d82..00000000 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/FixedUpdateMotionScheduler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 06d764af6da3342219c3090694cbcd46 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/LateUpdateMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/LateUpdateMotionScheduler.cs deleted file mode 100644 index 4edfc323..00000000 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/LateUpdateMotionScheduler.cs +++ /dev/null @@ -1,21 +0,0 @@ -using UnityEngine; - -namespace LitMotion -{ - internal sealed class LateUpdateMotionScheduler : IMotionScheduler - { - public MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) - where TValue : unmanaged - where TOptions : unmanaged, IMotionOptions - where TAdapter : unmanaged, IMotionAdapter - { -#if UNITY_EDITOR - if (!Application.isPlaying) - { - MotionDispatcher.Schedule(data, callbackData, UpdateMode.EditorApplicationUpdate); - } -#endif - return MotionDispatcher.Schedule(data, callbackData, UpdateMode.LateUpdate); - } - } -} \ No newline at end of file diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/LateUpdateMotionScheduler.cs.meta b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/LateUpdateMotionScheduler.cs.meta deleted file mode 100644 index f62c56e3..00000000 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/LateUpdateMotionScheduler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ad85431f1de234f569b83db1d2357ae8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/ManualMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/ManualMotionScheduler.cs index 145836ca..1c0b2829 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/ManualMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/ManualMotionScheduler.cs @@ -2,6 +2,8 @@ namespace LitMotion { internal sealed class ManualMotionScheduler : IMotionScheduler { + public double Time => ManualMotionDispatcher.Time; + public MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) where TValue : unmanaged where TOptions : unmanaged, IMotionOptions diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs index 0bd1cbeb..0c337abe 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs @@ -8,17 +8,17 @@ public static class MotionScheduler /// /// Scheduler that updates motion at Update. /// - public static readonly IMotionScheduler Update = new UpdateMotionScheduler(); + public static readonly IMotionScheduler Update = new PlayerLoopMotionScheduler(UpdateMode.Update, TimeKind.Time); /// /// Scheduler that updates motion at LateUpdate. /// - public static readonly IMotionScheduler LateUpdate = new LateUpdateMotionScheduler(); + public static readonly IMotionScheduler LateUpdate = new PlayerLoopMotionScheduler(UpdateMode.LateUpdate, TimeKind.Time); /// /// Scheduler that updates motion at FixedUpdate. /// - public static readonly IMotionScheduler FixedUpdate = new FixedUpdateMotionScheduler(); + public static readonly IMotionScheduler FixedUpdate = new PlayerLoopMotionScheduler(UpdateMode.LateUpdate, TimeKind.Time); /// /// Scheduler that updates motion with `ManualMotionDispatcher.Update()` diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs new file mode 100644 index 00000000..8f47c3b7 --- /dev/null +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs @@ -0,0 +1,64 @@ +using System; +using UnityTime = UnityEngine.Time; +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace LitMotion +{ + internal sealed class PlayerLoopMotionScheduler : IMotionScheduler + { + readonly UpdateMode updateMode; + readonly TimeKind timeKind; + + internal PlayerLoopMotionScheduler(UpdateMode updateMode, TimeKind timeKind) + { + this.updateMode = updateMode; + this.timeKind = timeKind; + } + + public double Time + { + get + { + if (updateMode == UpdateMode.FixedUpdate) + { + return timeKind switch + { + TimeKind.Time => UnityTime.fixedTimeAsDouble, + TimeKind.UnscaledTime => UnityTime.fixedUnscaledTimeAsDouble, + TimeKind.Realtime => UnityTime.realtimeSinceStartupAsDouble, + _ => throw new NotSupportedException("Invalid TimeKind") + }; + } + + return timeKind switch + { + TimeKind.Time => UnityTime.timeAsDouble, + TimeKind.UnscaledTime => UnityTime.unscaledTimeAsDouble, + TimeKind.Realtime => UnityTime.realtimeSinceStartupAsDouble, + _ => throw new NotSupportedException("Invalid TimeKind") + }; + } + } + + public MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) + where TValue : unmanaged + where TOptions : unmanaged, IMotionOptions + where TAdapter : unmanaged, IMotionAdapter + { +#if UNITY_EDITOR + if (EditorApplication.isPlayingOrWillChangePlaymode) + { + return MotionDispatcher.Schedule(data, callbackData, updateMode); + } + else + { + return MotionDispatcher.ScheduleOnEditor(data, callbackData); + } +#else + return MotionDispatcher.Schedule(data, callbackData, updateMode); +#endif + } + } +} \ No newline at end of file diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/UpdateMotionScheduler.cs.meta b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs.meta similarity index 83% rename from src/LitMotion/Assets/LitMotion/Runtime/Schedulers/UpdateMotionScheduler.cs.meta rename to src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs.meta index c959e66e..1ee7aa7d 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/UpdateMotionScheduler.cs.meta +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0ad084655c9194456a2b93c501f51873 +guid: b5520ca7608ac4abbb05c8fbf32e375a MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/UpdateMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/UpdateMotionScheduler.cs deleted file mode 100644 index 8500d99c..00000000 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/UpdateMotionScheduler.cs +++ /dev/null @@ -1,21 +0,0 @@ -using UnityEngine; - -namespace LitMotion -{ - internal sealed class UpdateMotionScheduler : IMotionScheduler - { - public MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) - where TValue : unmanaged - where TOptions : unmanaged, IMotionOptions - where TAdapter : unmanaged, IMotionAdapter - { -#if UNITY_EDITOR - if (!Application.isPlaying) - { - MotionDispatcher.Schedule(data, callbackData, UpdateMode.EditorApplicationUpdate); - } -#endif - return MotionDispatcher.Schedule(data, callbackData, UpdateMode.Update); - } - } -} \ No newline at end of file From 3146bbdeb008b989d5bd603a74c8b672a82b98dc Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 19:29:41 +0900 Subject: [PATCH 02/11] Fix: FixedUpdate Scheduler not running on FixedUpdate --- .../Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs index 0c337abe..8bf2e886 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs @@ -18,7 +18,7 @@ public static class MotionScheduler /// /// Scheduler that updates motion at FixedUpdate. /// - public static readonly IMotionScheduler FixedUpdate = new PlayerLoopMotionScheduler(UpdateMode.LateUpdate, TimeKind.Time); + public static readonly IMotionScheduler FixedUpdate = new PlayerLoopMotionScheduler(UpdateMode.FixedUpdate, TimeKind.Time); /// /// Scheduler that updates motion with `ManualMotionDispatcher.Update()` From 121cf7b6473a756354229590649a184d687cc8a3 Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 19:30:14 +0900 Subject: [PATCH 03/11] Fix: motion not working on Editor --- .../Assets/LitMotion/Runtime/MotionDispatcher.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs b/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs index 99650e2b..5a8c1d02 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs @@ -203,8 +203,6 @@ void ResetAll(MinimumList list) } #if UNITY_EDITOR - static double lastEditorTime; - internal static MotionHandle ScheduleOnEditor(in MotionData data, in MotionCallbackData callbackData) where TValue : unmanaged where TOptions : unmanaged, IMotionOptions @@ -230,19 +228,16 @@ internal static MotionHandle ScheduleOnEditor(in Mot [InitializeOnLoadMethod] static void InitEditor() { - lastEditorTime = 0f; EditorApplication.update += UpdateEditor; } static void UpdateEditor() { - var deltaTime = (float)(EditorApplication.timeSinceStartup - lastEditorTime); - var span = updateRunners.AsSpan(); + var span = editorApplicationUpdateRunners.AsSpan(); for (int i = 0; i < span.Length; i++) { - span[i]?.Update(deltaTime, deltaTime); + span[i].Update(EditorApplication.timeSinceStartup, EditorApplication.timeSinceStartup); } - lastEditorTime = EditorApplication.timeSinceStartup; } #endif } From 8c6c0ba2c4e6ca74fcfde5fcb3281fc7ed9e4f8c Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 20:04:59 +0900 Subject: [PATCH 04/11] Add: EditorMotionDispatcher (internal) --- .../Editor/EditorUpdateMotionScheduler.cs | 2 +- .../LitMotion/Runtime/MotionDispatcher.cs | 84 +++++++++++-------- .../Schedulers/PlayerLoopMotionScheduler.cs | 2 +- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs index 70c4a4c7..c5287c7f 100644 --- a/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs @@ -11,7 +11,7 @@ public MotionHandle Schedule(in MotionData { - return MotionDispatcher.ScheduleOnEditor(data, callbackData); + return EditorMotionDispatcher.Schedule(data, callbackData); } } } \ No newline at end of file diff --git a/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs b/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs index 5a8c1d02..68ee224f 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs @@ -30,9 +30,6 @@ static class StorageCache public static MotionStorage update; public static MotionStorage lateUpdate; public static MotionStorage fixedUpdate; -#if UNITY_EDITOR - public static MotionStorage editorApplicationUpdate; -#endif public static MotionStorage GetOrCreate(UpdateMode updateMode) { @@ -65,19 +62,6 @@ public static MotionStorage GetOrCreate(UpdateMode u return fixedUpdate; } } - -#if UNITY_EDITOR - public static MotionStorage GetOrCreateEditor() - { - if (editorApplicationUpdate == null) - { - var storage = new MotionStorage(MotionStorageManager.CurrentStorageId); - MotionStorageManager.AddStorage(storage); - editorApplicationUpdate = storage; - } - return editorApplicationUpdate; - } -#endif } static class RunnerCache @@ -88,18 +72,12 @@ static class RunnerCache public static UpdateRunner update; public static UpdateRunner lateUpdate; public static UpdateRunner fixedUpdate; -#if UNITY_EDITOR - public static UpdateRunner editorApplicationUpdate; -#endif } static readonly MinimumList updateRunners = new(); static readonly MinimumList lateUpdateRunners = new(); static readonly MinimumList fixedUpdateRunners = new(); -#if UNITY_EDITOR - static readonly MinimumList editorApplicationUpdateRunners = new(); -#endif - + /// /// Ensures the storage capacity until it reaches at least `capacity`. /// @@ -113,7 +91,7 @@ public static void EnsureStorageCapacity(int capacit StorageCache.GetOrCreate(UpdateMode.LateUpdate).EnsureCapacity(capacity); StorageCache.GetOrCreate(UpdateMode.FixedUpdate).EnsureCapacity(capacity); #if UNITY_EDITOR - StorageCache.GetOrCreateEditor().EnsureCapacity(capacity); + EditorMotionDispatcher.EnsureStorageCapacity(capacity); #endif } @@ -201,20 +179,48 @@ void ResetAll(MinimumList list) span[i].Reset(); } } + } #if UNITY_EDITOR - internal static MotionHandle ScheduleOnEditor(in MotionData data, in MotionCallbackData callbackData) + internal static class EditorMotionDispatcher + { + static class Cache where TValue : unmanaged where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter { - var storage = StorageCache.GetOrCreateEditor(); - if (RunnerCache.editorApplicationUpdate == null) + static MotionStorage storage; + static UpdateRunner updateRunner; + + public static MotionStorage GetOrCreateStorage() + { + if (storage == null) + { + storage = new MotionStorage(MotionStorageManager.CurrentStorageId); + MotionStorageManager.AddStorage(storage); + } + return storage; + } + + public static void InitUpdateRunner() { - var runner = new UpdateRunner(storage); - editorApplicationUpdateRunners.Add(runner); - RunnerCache.editorApplicationUpdate = runner; + if (updateRunner == null) + { + updateRunner = new UpdateRunner(storage); + updateRunners.Add(updateRunner); + } } + } + + static readonly MinimumList updateRunners = new(); + + public static MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) + where TValue : unmanaged + where TOptions : unmanaged, IMotionOptions + where TAdapter : unmanaged, IMotionAdapter + { + var storage = Cache.GetOrCreateStorage(); + Cache.InitUpdateRunner(); var (EntryIndex, Version) = storage.Append(data, callbackData); return new MotionHandle() @@ -225,20 +231,28 @@ internal static MotionHandle ScheduleOnEditor(in Mot }; } + public static void EnsureStorageCapacity(int capacity) + where TValue : unmanaged + where TOptions : unmanaged, IMotionOptions + where TAdapter : unmanaged, IMotionAdapter + { + Cache.GetOrCreateStorage().EnsureCapacity(capacity); + } + [InitializeOnLoadMethod] - static void InitEditor() + static void Init() { - EditorApplication.update += UpdateEditor; + EditorApplication.update += Update; } - static void UpdateEditor() + static void Update() { - var span = editorApplicationUpdateRunners.AsSpan(); + var span = updateRunners.AsSpan(); for (int i = 0; i < span.Length; i++) { span[i].Update(EditorApplication.timeSinceStartup, EditorApplication.timeSinceStartup); } } -#endif } +#endif } \ No newline at end of file diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs index 8f47c3b7..301e1dd7 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs @@ -54,7 +54,7 @@ public MotionHandle Schedule(in MotionData(data, callbackData); + return EditorMotionDispatcher.Schedule(data, callbackData); } #else return MotionDispatcher.Schedule(data, callbackData, updateMode); From 99993c3fa68de2dbd533352de39631d9862e79f0 Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 20:55:12 +0900 Subject: [PATCH 05/11] Change: IMotionScheduler.Schedule args to ref --- .../Editor/EditorUpdateMotionScheduler.cs | 2 +- .../External/UniRx/LitMotionUniRxExtensions.cs | 2 +- .../Assets/LitMotion/Runtime/IMotionScheduler.cs | 2 +- .../Assets/LitMotion/Runtime/MotionBuilder.cs | 14 +++++++------- .../Runtime/Schedulers/ManualMotionScheduler.cs | 2 +- .../Schedulers/PlayerLoopMotionScheduler.cs | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs index c5287c7f..7a75351e 100644 --- a/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Editor/EditorUpdateMotionScheduler.cs @@ -6,7 +6,7 @@ internal sealed class EditorUpdateMotionScheduler : IMotionScheduler { public double Time => EditorApplication.timeSinceStartup; - public MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) + public MotionHandle Schedule(ref MotionData data, ref MotionCallbackData callbackData) where TValue : unmanaged where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter diff --git a/src/LitMotion/Assets/LitMotion/Runtime/External/UniRx/LitMotionUniRxExtensions.cs b/src/LitMotion/Assets/LitMotion/Runtime/External/UniRx/LitMotionUniRxExtensions.cs index 8f94daa1..3d926d9a 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/External/UniRx/LitMotionUniRxExtensions.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/External/UniRx/LitMotionUniRxExtensions.cs @@ -29,7 +29,7 @@ public static IObservable ToObservable(this var scheduler = builder.buffer.Scheduler; var entity = builder.BuildMotionData(); - builder.Schedule(scheduler, entity, callbacks); + builder.Schedule(scheduler, ref entity, ref callbacks); return subject; } diff --git a/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs index a03b0301..c35f4fbf 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs @@ -14,7 +14,7 @@ public interface IMotionScheduler /// Motion data /// Motion callback data /// Motion handle - MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) + MotionHandle Schedule(ref MotionData data, ref MotionCallbackData callbackData) where TValue : unmanaged where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter; diff --git a/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs b/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs index 7de69924..5d770ec7 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs @@ -216,7 +216,7 @@ public MotionHandle RunWithoutBinding() var callbacks = BuildCallbackData(); var scheduler = buffer.Scheduler; var data = BuildMotionData(); - return Schedule(scheduler, data, callbacks); + return Schedule(scheduler, ref data, ref callbacks); } /// @@ -231,7 +231,7 @@ public MotionHandle Bind(Action action) callbacks.OnCompleteAction = buffer.OnComplete; var scheduler = buffer.Scheduler; var data = BuildMotionData(); - return Schedule(scheduler, data, callbacks); + return Schedule(scheduler, ref data, ref callbacks); } /// @@ -247,7 +247,7 @@ public MotionHandle BindWithState(TState state, Action a var callbacks = BuildCallbackData(state, action); var scheduler = buffer.Scheduler; var data = BuildMotionData(); - return Schedule(scheduler, data, callbacks); + return Schedule(scheduler, ref data, ref callbacks); } /// @@ -266,7 +266,7 @@ public MotionHandle BindWithState(TState1 state1, TState2 stat var callbacks = BuildCallbackData(state1, state2, action); var scheduler = buffer.Scheduler; var data = BuildMotionData(); - return Schedule(scheduler, data, callbacks); + return Schedule(scheduler, ref data, ref callbacks); } @@ -288,7 +288,7 @@ public MotionHandle BindWithState(TState1 state1, TSt var callbacks = BuildCallbackData(state1, state2, state3, action); var scheduler = buffer.Scheduler; var data = BuildMotionData(); - return Schedule(scheduler, data, callbacks); + return Schedule(scheduler, ref data, ref callbacks); } /// @@ -305,7 +305,7 @@ public readonly MotionBuilder Preserve() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal readonly MotionHandle Schedule(IMotionScheduler scheduler, in MotionData data, in MotionCallbackData callbackData) + internal readonly MotionHandle Schedule(IMotionScheduler scheduler, ref MotionData data, ref MotionCallbackData callbackData) { if (scheduler == null) { @@ -313,7 +313,7 @@ internal readonly MotionHandle Schedule(IMotionScheduler scheduler, in MotionDat } else { - return scheduler.Schedule(data, callbackData); + return scheduler.Schedule(ref data, ref callbackData); } } diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/ManualMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/ManualMotionScheduler.cs index 1c0b2829..505ba7c7 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/ManualMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/ManualMotionScheduler.cs @@ -4,7 +4,7 @@ internal sealed class ManualMotionScheduler : IMotionScheduler { public double Time => ManualMotionDispatcher.Time; - public MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) + public MotionHandle Schedule(ref MotionData data, ref MotionCallbackData callbackData) where TValue : unmanaged where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs index 301e1dd7..19ba6a67 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs @@ -42,7 +42,7 @@ public double Time } } - public MotionHandle Schedule(in MotionData data, in MotionCallbackData callbackData) + public MotionHandle Schedule(ref MotionData data, ref MotionCallbackData callbackData) where TValue : unmanaged where TOptions : unmanaged, IMotionOptions where TAdapter : unmanaged, IMotionAdapter From a0b458992294d3126e19711854fbf08647dd82dc Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 21:17:28 +0900 Subject: [PATCH 06/11] Remove: WithIgnoreTimeScale --- .../LitMotion/Runtime/IMotionScheduler.cs | 11 +++++++---- .../LitMotion/Runtime/Internal/MotionData.cs | 2 +- .../Assets/LitMotion/Runtime/MotionBuilder.cs | 16 ---------------- .../Assets/LitMotion/Runtime/MotionUpdateJob.cs | 11 ++++++++++- .../Runtime/Schedulers/MotionScheduler.cs | 6 +++--- .../Schedulers/PlayerLoopMotionScheduler.cs | 17 +++++++++-------- 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs index c35f4fbf..c955ddaf 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/IMotionScheduler.cs @@ -25,10 +25,13 @@ MotionHandle Schedule(ref MotionData + /// Type of time used to play the motion + /// + public enum MotionTimeKind : byte { - Time, - UnscaledTime, - Realtime + Time = 0, + UnscaledTime = 1, + Realtime = 2 } } \ No newline at end of file diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Internal/MotionData.cs b/src/LitMotion/Assets/LitMotion/Runtime/Internal/MotionData.cs index 18d58a85..c13d71ce 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Internal/MotionData.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Internal/MotionData.cs @@ -18,7 +18,7 @@ public struct MotionData public float Duration; public Ease Ease; - public bool IgnoreTimeScale; + public MotionTimeKind TimeKind; public float Delay; public int Loops; public LoopType LoopType; diff --git a/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs b/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs index 5d770ec7..445bdbf8 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/MotionBuilder.cs @@ -27,7 +27,6 @@ public static void Return(MotionBuilderBuffer buffer) buffer.Version++; buffer.Duration = default; buffer.Ease = default; - buffer.IgnoreTimeScale = default; buffer.Delay = default; buffer.Loops = 1; buffer.LoopType = default; @@ -50,7 +49,6 @@ public static void Return(MotionBuilderBuffer buffer) public float Duration; public Ease Ease; - public bool IgnoreTimeScale; public float Delay; public int Loops = 1; public LoopType LoopType; @@ -100,19 +98,6 @@ public readonly MotionBuilder WithEase(Ease ease) return this; } - /// - /// Specify whether motion ignores time scale. - /// - /// If true, time scale will be ignored - /// This builder to allow chaining multiple method calls. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly MotionBuilder WithIgnoreTimeScale(bool ignoreTimeScale = true) - { - CheckBuffer(); - buffer.IgnoreTimeScale = ignoreTimeScale; - return this; - } - /// /// Specify the delay time when the motion starts. /// @@ -338,7 +323,6 @@ internal MotionData BuildMotionData() StartTime = buffer.Scheduler == null ? MotionScheduler.Update.Time : buffer.Scheduler.Time, Duration = buffer.Duration, Ease = buffer.Ease, - IgnoreTimeScale = buffer.IgnoreTimeScale, Delay = buffer.Delay, Loops = buffer.Loops, LoopType = buffer.LoopType, diff --git a/src/LitMotion/Assets/LitMotion/Runtime/MotionUpdateJob.cs b/src/LitMotion/Assets/LitMotion/Runtime/MotionUpdateJob.cs index e3958efb..8cb1276e 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/MotionUpdateJob.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/MotionUpdateJob.cs @@ -22,6 +22,7 @@ public unsafe struct MotionUpdateJob : IJobParallelF [NativeDisableUnsafePtrRestriction] public MotionData* DataPtr; [ReadOnly] public double Time; [ReadOnly] public double UnscaledTime; + [ReadOnly] public double Realtime; [WriteOnly] public NativeList.ParallelWriter CompletedIndexList; [WriteOnly] public NativeArray Output; @@ -32,7 +33,15 @@ public void Execute([AssumeRange(0, int.MaxValue)] int index) if (Hint.Likely(ptr->Status is MotionStatus.Scheduled or MotionStatus.Delayed or MotionStatus.Playing)) { - var motionTime = (ptr->IgnoreTimeScale ? UnscaledTime : Time) - ptr->StartTime; + var currentTime = ptr->TimeKind switch + { + MotionTimeKind.Time => Time, + MotionTimeKind.UnscaledTime => UnscaledTime, + MotionTimeKind.Realtime => Realtime, + _ => default + }; + + var motionTime = currentTime - ptr->StartTime; var time = motionTime - ptr->Delay; double t; diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs index 8bf2e886..5c11c8cf 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs @@ -8,17 +8,17 @@ public static class MotionScheduler /// /// Scheduler that updates motion at Update. /// - public static readonly IMotionScheduler Update = new PlayerLoopMotionScheduler(UpdateMode.Update, TimeKind.Time); + public static readonly IMotionScheduler Update = new PlayerLoopMotionScheduler(UpdateMode.Update, MotionTimeKind.Time); /// /// Scheduler that updates motion at LateUpdate. /// - public static readonly IMotionScheduler LateUpdate = new PlayerLoopMotionScheduler(UpdateMode.LateUpdate, TimeKind.Time); + public static readonly IMotionScheduler LateUpdate = new PlayerLoopMotionScheduler(UpdateMode.LateUpdate, MotionTimeKind.Time); /// /// Scheduler that updates motion at FixedUpdate. /// - public static readonly IMotionScheduler FixedUpdate = new PlayerLoopMotionScheduler(UpdateMode.FixedUpdate, TimeKind.Time); + public static readonly IMotionScheduler FixedUpdate = new PlayerLoopMotionScheduler(UpdateMode.FixedUpdate, MotionTimeKind.Time); /// /// Scheduler that updates motion with `ManualMotionDispatcher.Update()` diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs index 19ba6a67..f6ab42de 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/PlayerLoopMotionScheduler.cs @@ -9,9 +9,9 @@ namespace LitMotion internal sealed class PlayerLoopMotionScheduler : IMotionScheduler { readonly UpdateMode updateMode; - readonly TimeKind timeKind; + readonly MotionTimeKind timeKind; - internal PlayerLoopMotionScheduler(UpdateMode updateMode, TimeKind timeKind) + internal PlayerLoopMotionScheduler(UpdateMode updateMode, MotionTimeKind timeKind) { this.updateMode = updateMode; this.timeKind = timeKind; @@ -25,18 +25,18 @@ public double Time { return timeKind switch { - TimeKind.Time => UnityTime.fixedTimeAsDouble, - TimeKind.UnscaledTime => UnityTime.fixedUnscaledTimeAsDouble, - TimeKind.Realtime => UnityTime.realtimeSinceStartupAsDouble, + MotionTimeKind.Time => UnityTime.fixedTimeAsDouble, + MotionTimeKind.UnscaledTime => UnityTime.fixedUnscaledTimeAsDouble, + MotionTimeKind.Realtime => UnityTime.realtimeSinceStartupAsDouble, _ => throw new NotSupportedException("Invalid TimeKind") }; } return timeKind switch { - TimeKind.Time => UnityTime.timeAsDouble, - TimeKind.UnscaledTime => UnityTime.unscaledTimeAsDouble, - TimeKind.Realtime => UnityTime.realtimeSinceStartupAsDouble, + MotionTimeKind.Time => UnityTime.timeAsDouble, + MotionTimeKind.UnscaledTime => UnityTime.unscaledTimeAsDouble, + MotionTimeKind.Realtime => UnityTime.realtimeSinceStartupAsDouble, _ => throw new NotSupportedException("Invalid TimeKind") }; } @@ -47,6 +47,7 @@ public MotionHandle Schedule(ref MotionData { + data.TimeKind = timeKind; #if UNITY_EDITOR if (EditorApplication.isPlayingOrWillChangePlaymode) { From 746fccbe7cfc0dc81697b5588c7a673a600c4170 Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 21:36:29 +0900 Subject: [PATCH 07/11] Add: realtime timekind --- .../Assets/LitMotion/Runtime/Internal/UpdateRunner.cs | 5 +++-- .../Assets/LitMotion/Runtime/ManualMotionDispatcher.cs | 2 +- .../Assets/LitMotion/Runtime/MotionDispatcher.cs | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Internal/UpdateRunner.cs b/src/LitMotion/Assets/LitMotion/Runtime/Internal/UpdateRunner.cs index dfd0baf8..3749ddeb 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Internal/UpdateRunner.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Internal/UpdateRunner.cs @@ -8,7 +8,7 @@ namespace LitMotion { internal interface IUpdateRunner { - public void Update(double time, double unscaledTime); + public void Update(double time, double unscaledTime, double realtime); public void Reset(); } @@ -24,7 +24,7 @@ public UpdateRunner(MotionStorage storage) readonly MotionStorage storage; - public unsafe void Update(double time, double unscaledTime) + public unsafe void Update(double time, double unscaledTime, double realtime) { var count = storage.Count; using var output = new NativeArray(count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); @@ -38,6 +38,7 @@ public unsafe void Update(double time, double unscaledTime) DataPtr = dataPtr, Time = time, UnscaledTime = unscaledTime, + Realtime = realtime, Output = output, CompletedIndexList = completedIndexList.AsParallelWriter() }; diff --git a/src/LitMotion/Assets/LitMotion/Runtime/ManualMotionDispatcher.cs b/src/LitMotion/Assets/LitMotion/Runtime/ManualMotionDispatcher.cs index 04b521ec..8414dc90 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/ManualMotionDispatcher.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/ManualMotionDispatcher.cs @@ -65,7 +65,7 @@ public static void Update() var span = updateRunners.AsSpan(); for (int i = 0; i < span.Length; i++) { - span[i].Update(Time, Time); + span[i].Update(Time, Time, Time); } } diff --git a/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs b/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs index 68ee224f..584027d2 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs @@ -149,19 +149,19 @@ static void Init() void Update() { var span = updateRunners.AsSpan(); - for (int i = 0; i < span.Length; i++) span[i].Update(Time.timeAsDouble, Time.unscaledTimeAsDouble); + for (int i = 0; i < span.Length; i++) span[i].Update(Time.timeAsDouble, Time.unscaledTimeAsDouble, Time.realtimeSinceStartupAsDouble); } void LateUpdate() { var span = lateUpdateRunners.AsSpan(); - for (int i = 0; i < span.Length; i++) span[i].Update(Time.timeAsDouble, Time.unscaledTimeAsDouble); + for (int i = 0; i < span.Length; i++) span[i].Update(Time.timeAsDouble, Time.unscaledTimeAsDouble, Time.realtimeSinceStartupAsDouble); } void FixedUpdate() { var span = fixedUpdateRunners.AsSpan(); - for (int i = 0; i < span.Length; i++) span[i].Update(Time.fixedTime, Time.fixedTimeAsDouble); + for (int i = 0; i < span.Length; i++) span[i].Update(Time.fixedTime, Time.fixedTimeAsDouble, Time.realtimeSinceStartupAsDouble); } void OnDestroy() @@ -250,7 +250,7 @@ static void Update() var span = updateRunners.AsSpan(); for (int i = 0; i < span.Length; i++) { - span[i].Update(EditorApplication.timeSinceStartup, EditorApplication.timeSinceStartup); + span[i].Update(EditorApplication.timeSinceStartup, EditorApplication.timeSinceStartup, Time.realtimeSinceStartupAsDouble); } } } From 6754656c537a14e8a3d48a0ce159e21fe7c0ea7f Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 21:47:10 +0900 Subject: [PATCH 08/11] Add: IgnoreTimeScale/Realtime schedulers --- .../Runtime/Schedulers/MotionScheduler.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs index 5c11c8cf..dafa87b9 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs @@ -20,6 +20,36 @@ public static class MotionScheduler /// public static readonly IMotionScheduler FixedUpdate = new PlayerLoopMotionScheduler(UpdateMode.FixedUpdate, MotionTimeKind.Time); + /// + /// Scheduler that updates motion at Update. (Ignore timescale) + /// + public static readonly IMotionScheduler UpdateIgnoreTimeScale = new PlayerLoopMotionScheduler(UpdateMode.Update, MotionTimeKind.UnscaledTime); + + /// + /// Scheduler that updates motion at LateUpdate. (Ignore timescale) + /// + public static readonly IMotionScheduler LateUpdateIgnoreTimeScale = new PlayerLoopMotionScheduler(UpdateMode.LateUpdate, MotionTimeKind.UnscaledTime); + + /// + /// Scheduler that updates motion at FixedUpdate. (Ignore timescale) + /// + public static readonly IMotionScheduler FixedUpdateIgnoreTimeScale = new PlayerLoopMotionScheduler(UpdateMode.FixedUpdate, MotionTimeKind.UnscaledTime); + + /// + /// Scheduler that updates motion at Update. (Realtime) + /// + public static readonly IMotionScheduler UpdateRealtime = new PlayerLoopMotionScheduler(UpdateMode.Update, MotionTimeKind.Realtime); + + /// + /// Scheduler that updates motion at LateUpdate. (Realtime) + /// + public static readonly IMotionScheduler LateUpdateRealtime = new PlayerLoopMotionScheduler(UpdateMode.LateUpdate, MotionTimeKind.Realtime); + + /// + /// Scheduler that updates motion at FixedUpdate. (Realtime) + /// + public static readonly IMotionScheduler FixedUpdateRealtime = new PlayerLoopMotionScheduler(UpdateMode.FixedUpdate, MotionTimeKind.Realtime); + /// /// Scheduler that updates motion with `ManualMotionDispatcher.Update()` /// From e05a2a4ce6c00f62712aa6286612e9435b44f0c6 Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 22:03:59 +0900 Subject: [PATCH 09/11] Fix: FixedUpdateIgnoreTimeScale not working --- src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs b/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs index 584027d2..b21e0619 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/MotionDispatcher.cs @@ -161,7 +161,7 @@ void LateUpdate() void FixedUpdate() { var span = fixedUpdateRunners.AsSpan(); - for (int i = 0; i < span.Length; i++) span[i].Update(Time.fixedTime, Time.fixedTimeAsDouble, Time.realtimeSinceStartupAsDouble); + for (int i = 0; i < span.Length; i++) span[i].Update(Time.fixedTimeAsDouble, Time.fixedUnscaledTimeAsDouble, Time.realtimeSinceStartupAsDouble); } void OnDestroy() From e77b23faedc469b43b4a7ead34ea6224d0bda5c8 Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 22:18:04 +0900 Subject: [PATCH 10/11] Remove: FixedUpdateIgnoreTimeScale/Realtime --- .../LitMotion/Runtime/Schedulers/MotionScheduler.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs index dafa87b9..dc0640ba 100644 --- a/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs +++ b/src/LitMotion/Assets/LitMotion/Runtime/Schedulers/MotionScheduler.cs @@ -30,11 +30,6 @@ public static class MotionScheduler /// public static readonly IMotionScheduler LateUpdateIgnoreTimeScale = new PlayerLoopMotionScheduler(UpdateMode.LateUpdate, MotionTimeKind.UnscaledTime); - /// - /// Scheduler that updates motion at FixedUpdate. (Ignore timescale) - /// - public static readonly IMotionScheduler FixedUpdateIgnoreTimeScale = new PlayerLoopMotionScheduler(UpdateMode.FixedUpdate, MotionTimeKind.UnscaledTime); - /// /// Scheduler that updates motion at Update. (Realtime) /// @@ -45,11 +40,6 @@ public static class MotionScheduler /// public static readonly IMotionScheduler LateUpdateRealtime = new PlayerLoopMotionScheduler(UpdateMode.LateUpdate, MotionTimeKind.Realtime); - /// - /// Scheduler that updates motion at FixedUpdate. (Realtime) - /// - public static readonly IMotionScheduler FixedUpdateRealtime = new PlayerLoopMotionScheduler(UpdateMode.FixedUpdate, MotionTimeKind.Realtime); - /// /// Scheduler that updates motion with `ManualMotionDispatcher.Update()` /// From 92accfd53f6baf0d7515a64d28bb0e7d71e61d8d Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Mon, 15 Jan 2024 22:18:11 +0900 Subject: [PATCH 11/11] Add: tests --- .../LitMotion/Tests/Runtime/SchedulerTest.cs | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/LitMotion/Assets/LitMotion/Tests/Runtime/SchedulerTest.cs b/src/LitMotion/Assets/LitMotion/Tests/Runtime/SchedulerTest.cs index ddc47096..9f3bddbb 100644 --- a/src/LitMotion/Assets/LitMotion/Tests/Runtime/SchedulerTest.cs +++ b/src/LitMotion/Assets/LitMotion/Tests/Runtime/SchedulerTest.cs @@ -7,10 +7,67 @@ namespace LitMotion.Tests.Runtime { public class SchedulerTest { + const float Duration = 0.2f; + + [TearDown] + public void TearDown() + { + Time.timeScale = 1; + } + + [UnityTest] + public IEnumerator Test_Scheduler_Update_IgnoreTimeScale() + { + Time.timeScale = 0; + yield return LMotion.Create(0f, 10f, Duration) + .WithScheduler(MotionScheduler.UpdateIgnoreTimeScale) + .RunWithoutBinding() + .ToYieldInteraction(); + } + + [UnityTest] + public IEnumerator Test_Scheduler_Update_Realtime() + { + Time.timeScale = 0; + yield return LMotion.Create(0f, 10f, Duration) + .WithScheduler(MotionScheduler.UpdateRealtime) + .RunWithoutBinding() + .ToYieldInteraction(); + } + + [UnityTest] + public IEnumerator Test_Scheduler_LateUpdate() + { + yield return LMotion.Create(0f, 10f, Duration) + .WithScheduler(MotionScheduler.LateUpdate) + .RunWithoutBinding() + .ToYieldInteraction(); + } + + [UnityTest] + public IEnumerator Test_Scheduler_LateUpdate_IgnoreTimeScale() + { + Time.timeScale = 0; + yield return LMotion.Create(0f, 10f, Duration) + .WithScheduler(MotionScheduler.LateUpdateIgnoreTimeScale) + .RunWithoutBinding() + .ToYieldInteraction(); + } + + [UnityTest] + public IEnumerator Test_Scheduler_LateUpdate_Realtime() + { + Time.timeScale = 0; + yield return LMotion.Create(0f, 10f, Duration) + .WithScheduler(MotionScheduler.LateUpdateRealtime) + .RunWithoutBinding() + .ToYieldInteraction(); + } + [UnityTest] public IEnumerator Test_Scheduler_FixedUpdate() { - yield return LMotion.Create(0f, 10f, 1f) + yield return LMotion.Create(0f, 10f, Duration) .WithScheduler(MotionScheduler.FixedUpdate) .Bind(x => {