DontDestroyOnLoad errors
a-gms opened this issue · 3 comments
Existence of DontDestroyOnLoad(go) in PrimeTweenManager causes below errors when changing scenes. After removing this line, they go away:
AssertionException: Add 'PRIME_TWEEN_SAFETY_CHECKS' to 'Project Settings/Player/Scripting Define Symbols' to see which tween produced this error (works only in Development Builds).
Assertion failure. Value was False
Expected: True
UnityEngine.Assertions.Assert.Fail (System.String message, System.String userMessage) (at <30adf90198bc4c4b83910c6fb1877998>:0)
UnityEngine.Assertions.Assert.IsTrue (System.Boolean condition, System.String message) (at <30adf90198bc4c4b83910c6fb1877998>:0)
PrimeTween.Assert.IsTrue (System.Boolean condition, System.Nullable`1[T] tweenId, System.String msg) (at Assets/Scripts/PrimeTween/Runtime/Internal/Assert.cs:23)
PrimeTween.ReusableTween.getSequenceSelfChildren (System.Boolean isForward) (at Assets/Scripts/PrimeTween/Runtime/Internal/ReusableTween.cs:177)
PrimeTween.ReusableTween.updateSequence (System.Single _elapsedTimeTotal, System.Boolean isRestart) (at Assets/Scripts/PrimeTween/Runtime/Internal/ReusableTween.cs:168)
PrimeTween.ReusableTween.SetElapsedTimeTotal (System.Single newElapsedTimeTotal) (at Assets/Scripts/PrimeTween/Runtime/Internal/ReusableTween.cs:81)
PrimeTween.ReusableTween.updateAndCheckIfRunning (System.Single dt) (at Assets/Scripts/PrimeTween/Runtime/Internal/ReusableTween.cs:68)
PrimeTween.PrimeTweenManager.update (System.Collections.Generic.List`1[T] tweens, System.Single deltaTime, System.Single unscaledDeltaTime, System.Int32& processedCount) (at Assets/Scripts/PrimeTween/Runtime/Internal/PrimeTweenManager.cs:161)
PrimeTween.PrimeTweenManager.Update () (at Assets/Scripts/PrimeTween/Runtime/Internal/PrimeTweenManager.cs:139)
and continuous spam of
Exception: updateDepth != 0
PrimeTween.PrimeTweenManager.update (System.Collections.Generic.List`1[T] tweens, System.Single deltaTime, System.Single unscaledDeltaTime, System.Int32& processedCount) (at Assets/Scripts/PrimeTween/Runtime/Internal/PrimeTweenManager.cs:143)
PrimeTween.PrimeTweenManager.Update () (at Assets/Scripts/PrimeTween/Runtime/Internal/PrimeTweenManager.cs:139)
Huge thanks for the bug report!
Could you please show me what sequence in your project causes the error and in what situation? I've been chasing this bug for a week already and I can't come up with an example that reproduces the issue, so I would very much appreciate a small reproducible project.
You can see the exact place that started the sequence that produces the error by adding the PRIME_TWEEN_SAFETY_CHECKS define to 'Project Settings/Player/Scripting Define Symbols'. With this define present, PrimeTween will show the stack trace that creates the problematic sequence. Please share the code snippet that creates the sequence and tell me in which moments in your game you call sequence.Stop/Complete() on that sequence.
there is no stop/complete on this sequence, but it shows up on tween stack trace after scene change.
Sequence sequence1 = Sequence.Create();
sequence1.Chain(
Tween.Rotation(gameObject.transform, endValue: new Vector3(0, 0, -2.5f),
duration: 1.5f, ease: Ease.InOutSine, cycles: 1)
);
sequence1.Chain(
Tween.Rotation(gameObject.transform, endValue: new Vector3(0, 0, 2.5f),
duration: 1.5f, ease: Ease.InOutSine, cycles: 1111,
cycleMode: CycleMode.Yoyo)
);
return null;
The issue is fixed in version 1.1.7. Huge thanks for the bug report!
Here are some technical details as to what caused the issue.
ReusableTween class has a serializable unityTarget
field. It's serializable to let users view the tween's target in the Inspector.
[SerializeField] internal UnityEngine.Object unityTarget;
The unityTarget
is populated by PrimeTween when a tween's target is derived from UnityEngine.Object (Transfrom, MonoBehaviour, etc.). In the case of sequences and tweens that animate non-UnityEngine.Object the unityTarget
is set to null.
To correctly support object destruction, PrimeTween uses this method to check if obj is UnityEngine.Object, then calls a special Unity null check on it via the overloaded ==
operator:
internal static bool isDestroyedUnityObject<T>(T obj) where T: class {
return obj is UnityEngine.Object unityObject && unityObject == null;
}
When a new scene is loaded in the Editor, Unity runs the seriazation process on all serializable objects, including all ReusableTween. But because Unity's serialization doesn't support null values, unityTarget
will be populated with a fake non-null value, and the isDestroyedUnityObject() will erroneously return true, killing all sequences and tweens with non-UnityEngine.Object targets and causing the bug.
This weird and unexpected bug happened only in Editor because serialization doesn't happen in real builds.
Huge thanks to NFMynster and @a-gms for helping me to reproduce and fix the issue!