Is it safe to destroy an object with a running tween on it? #4
Replies: 6 comments 12 replies
-
What would be the correct approach to do a coin animation that adds the coins once the animation finished in a situation where the level could finish before the end of the animation? The solution of moving the important method outside the callback doesn't really work in this scenario as it changes behaviour. We also cannot ignore that as a cosmetic change because then the player will lose those coins. |
Beta Was this translation helpful? Give feedback.
-
Would love for this to also be configurable globally, ie |
Beta Was this translation helpful? Give feedback.
-
Is Sequence.ChainDelay missing the |
Beta Was this translation helpful? Give feedback.
-
It doesn't matter because Sequence.ChainDelay() doesn't have the callback. 'warnIfTargetDestroyed' is only present in methods that have callbacks.
Changing the default value of 'warnIfTargetDestroyed' from true to false will make it a lot harder for users to debug problems related to destroying objects. Oftentimes, users new to Unity and C# are not aware of this potential problem at all. So I decided to go on the safe path and treat all OnComplete() callbacks as 'business critical' by default, leaving it to users to decide on a case-by-case basis if it's safe to ignore the particular callback or not.
Tween.StopAll() stops all tweens and sequences. Or do you wish to have a separate Sequence.StopAll() method that will stop only sequences? |
Beta Was this translation helpful? Give feedback.
-
For me It doesn't work, I catch an error |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Is it safe to destroy an object with a running tween on it?
The short answer is yes! It's safe to destroy an object with a running tween. If the tween's target is UnityEngine.Object, then PrimeTween will check if it's not destroyed before playing an animation further. This means you shouldn't care if an object has running tweens before destroying it or before unloading a scene.
But if a tween has an
OnComplete()
callback, and the tween's target gets destroyed, then what?'warnIfTargetDestroyed' parameter
PrimeTween never silents errors or potential places where a bug can occur in a user's code. So the solution to this problem is simple - log an error that OnComplete() will not be called because of the interruption. This attracts the user's attention to the potential problem and lets them fix it correctly.
So the rule of thumb is to NOT use the OnComplete() for important actions if you expect the tween's target to be destroyed mid-way. If you're using OnComplete() only for cosmetics, then pass the
warnIfTargetDestroyed: false
parameter to the OnComplete() method to silence PrimeTween's warning.Coin indicator example.
Let's consider the next piece of code. It animates the coinIndicator, then gives coins to the player, and updates the label:
The issue with the above code is that if the coinIndicator is destroyed (or the scene is unloaded) before the animation finishes, the AddCoins(100) method will not be called, and the player will not receive their hard-earned coins. If this happens, PrimeTween will warn about that with an error to the console.
Here is a fixed version that executes only cosmetics code in OnComplete() callback:
Notice that the important AddCoins(100) method is called independently from the animation, and the OnComplete() method only updates the label. The
warnIfTargetDestroyed
is set to false to tell PrimeTween that the callback is safe to ignore if coinIndicator gets destroyed mid-way.Why not add the 'OnTargetDestroyed()' callback to the tween?
If you want to do some kind of clean-up when tween's target gets destroyed, then such a callback will not solve the problem, but will only make it worse. Let's consider a hypothetical example:
After the transform is destroyed, it's most likely too late to do the clean-ups: (1) you can't do any operations with the transform; (2) you can't do any operations with the MonoBehaviour that started the tween because the references it holds may already be destroyed too.
The correct way to address these kinds of problems is to do a clean-up manually before you destroy the target. This way, you'll not only prevent all kinds of MissingReferenceException but will also make your code more readable and reliable.
Beta Was this translation helpful? Give feedback.
All reactions