diff --git a/Packages/com.shlifedev.floating-text-render-feature/Runtime/DefaultFloatingTextAnimator.cs b/Packages/com.shlifedev.floating-text-render-feature/Runtime/DefaultFloatingTextAnimator.cs index b41862e..c34d0c0 100644 --- a/Packages/com.shlifedev.floating-text-render-feature/Runtime/DefaultFloatingTextAnimator.cs +++ b/Packages/com.shlifedev.floating-text-render-feature/Runtime/DefaultFloatingTextAnimator.cs @@ -37,6 +37,7 @@ public override void Evaluate(float elapsed, float duration, : 1f - EaseInQuad(Mathf.Clamp01(alphaElapsed / fadeDuration)); } + // FloatingTextAnimator.ScheduleEvaluateBatch must be overridden with a Burst-compatible batch path. public override JobHandle ScheduleEvaluateBatch( NativeArray entries, NativeArray results) diff --git a/Packages/com.shlifedev.floating-text-render-feature/Runtime/FloatingTextAnimator.cs b/Packages/com.shlifedev.floating-text-render-feature/Runtime/FloatingTextAnimator.cs index 8727833..86cfd4e 100644 --- a/Packages/com.shlifedev.floating-text-render-feature/Runtime/FloatingTextAnimator.cs +++ b/Packages/com.shlifedev.floating-text-render-feature/Runtime/FloatingTextAnimator.cs @@ -1,6 +1,9 @@ using Unity.Collections; using Unity.Jobs; using UnityEngine; +#if UNITY_ASSERTIONS +using UnityEngine.Assertions; +#endif namespace LD.FloatingTextRenderFeature { @@ -10,6 +13,10 @@ namespace LD.FloatingTextRenderFeature /// public abstract class FloatingTextAnimator : ScriptableObject { +#if DEVELOPMENT_BUILD || UNITY_EDITOR + private static bool s_loggedManagedFallbackWarning; +#endif + /// /// Evaluate animation values at the given time. /// @@ -29,6 +36,22 @@ public virtual JobHandle ScheduleEvaluateBatch( NativeArray entries, NativeArray results) { +#if UNITY_ASSERTIONS + Assert.IsTrue(false, + $"[{nameof(FloatingTextAnimator)}] {GetType().Name} is using managed fallback in {nameof(ScheduleEvaluateBatch)}(). " + + "Override ScheduleEvaluateBatch() and provide a Burst-compatible job for production use."); +#endif + +#if DEVELOPMENT_BUILD || UNITY_EDITOR + if (!s_loggedManagedFallbackWarning) + { + s_loggedManagedFallbackWarning = true; + Debug.LogWarning( + $"[{nameof(FloatingTextAnimator)}] {GetType().Name} did not override {nameof(ScheduleEvaluateBatch)}(). " + + "Falling back to managed Evaluate() loop. Implement a Burst job to avoid per-frame main-thread cost."); + } +#endif + for (int i = 0; i < entries.Length; i++) { var e = entries[i]; diff --git a/Packages/com.shlifedev.floating-text-render-feature/Runtime/FloatingTextManager.cs b/Packages/com.shlifedev.floating-text-render-feature/Runtime/FloatingTextManager.cs index 0290e20..5d7168c 100644 --- a/Packages/com.shlifedev.floating-text-render-feature/Runtime/FloatingTextManager.cs +++ b/Packages/com.shlifedev.floating-text-render-feature/Runtime/FloatingTextManager.cs @@ -6,6 +6,9 @@ using Unity.Mathematics; using UnityEngine; using UnityEngine.AddressableAssets; +#if UNITY_ASSERTIONS +using UnityEngine.Assertions; +#endif #if UNITY_EDITOR using UnityEditor; #endif @@ -255,7 +258,10 @@ private void LateUpdate() EnsureDigitOutputCapacity(totalDigits); - // ── Phase 3: Evaluate animation (Burst job or managed fallback) ── + // ── Phase 3: Evaluate animation (custom animator must provide ScheduleEvaluateBatch Burst job) ── +#if UNITY_ASSERTIONS + Assert.IsNotNull(_animator, $"[{nameof(FloatingTextManager)}] Animator is null."); +#endif JobHandle animHandle = _animator.ScheduleEvaluateBatch( _nativeEntries.GetSubArray(0, count), _animResults.GetSubArray(0, count)); diff --git a/README.md b/README.md index 4b0a491..36d190e 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,18 @@ FloatingTextManager.Instance.Show(worldPosition, damage); FloatingTextManager.Instance.Show(worldPosition, damage, duration: 1.0f, scale: 1.5f); ``` +## 커스텀 Animator 작성 규칙 + +`FloatingTextAnimator`를 상속해 커스텀 애니메이터를 만들 때는 아래 규칙을 지켜주세요. + +- `Evaluate(...)`는 단일 엔트리 계산 로직(수학식) 정의용입니다. +- `ScheduleEvaluateBatch(...)`는 **반드시 override** 해서 `IJobFor`/`IJobParallelFor` 기반의 Burst job을 스케줄해야 합니다. +- `FloatingTextManager`는 매 프레임 `_animator.ScheduleEvaluateBatch(...)`를 호출합니다. + - 미구현 시 managed fallback(`Evaluate` 루프)으로 진입하며, 개발 빌드/에디터에서는 경고 로그가 1회 출력됩니다. + - `UNITY_ASSERTIONS` 환경에서는 런타임 assert로 구현 누락을 빠르게 감지합니다. + +권장: 기본 구현은 `DefaultFloatingTextAnimator`의 `ScheduleEvaluateBatch` 예제를 참고하세요. + ## Font Sprite Generator `Window > Floating Text > Font Sprite Generator` 메뉴에서 접근할 수 있는 에디터 도구입니다.