- Home /
Delete Object After Animation (2D)
Alright, so there's plenty of information on how to do this with 3D animations, but I'm stumped with Unity 4 on how to do this in 2D. I have a very short animation, it's close to a second long, what I want to do is have it play once, and then delete itself. I tried doing:
if (!animation.isPlaying) {
Destroy (gameObject);
}
However, this gives me an error saying there is not animation connected. The only other way is to calculate how long the animation is in total, and then set a timer to delete after it's done, however that gives me little flexibility. What am I supposed to do, how would I achieve this?
I think your first approach is fine as long as the animation is playing when you start the scene. But you shouldn't get the error you got if things are setup right. You have a game object with an Animation component on it with at least 1 Animation in the Animations list on that component, in the Inspector. Then you attach the script above to that same game object. It should work. Is this not how you set your scene up? Could you describe, by Animation, do you mean an Animation Component?
I use this way of doing it, if I try doing the way you say it gives me a warning about the animation having to be in Legacy.
Well you said you were using animation, not animator. I was kind of wondering, should have asked you. :)
Answer by firestoke · Apr 06, 2016 at 09:20 AM
Here is my solution:
I create a script named "AnimationAutoDestroy", and add this component to the animator game object which you want to auto-destroy while animation is finished. You can adjust the delay time as you want.
using UnityEngine;
using System.Collections;
public class AnimationAutoDestroy : MonoBehaviour {
public float delay = 0f;
// Use this for initialization
void Start () {
Destroy (gameObject, this.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).length + delay);
}
}
Please note that this does not take the animation speed into account, and probably other parameters that could be useful in the future. The right way to do this is in the answer by @vElumi
Answer by vElumi · Jul 22, 2019 at 06:30 PM
You can use StateMachineBehaviour.
- In animator, select state. Game object will be destroyed after animation on that state will have finished.
- Click Add Behaviour
- Override OnStateEnter in your script:
public class DestroyOnExit : StateMachineBehaviour {
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
Destroy(animator.gameObject, stateInfo.length);
}
}
Thus you schedule object deletion just when animation has finished.
Also account for stateInfo.speed
or stateInfo.speedMultiplier
Also make sure that "loop time" is unchecked on the .anim file you are using. Otherwise, one frame of the beginning of the animation will appear before it is destroyed.
Answer by AssmeisTer · Oct 12, 2014 at 04:22 AM
A better solution that takes into account the length of the animation clip.
Code (csharp):
private int currentHealth;
public void TakeDamage(int damage)
{
currentHealth -= damage;
if (currentHealth <= 0)
{
StartCoroutine(Die());
}
}
private IEnumerator Die()
{
PlayAnimation(GlobalSettings.animDeath1, WrapeMode.ClampForever);
yield return new WaitForSeconds(gameObject, GlobalSettings.animDeath1.length);
Destroy(gameObject);
}
The code you have has StartCoroutine in Update which isn't good because it will kick off a new coroutine every frame.
Answer by Tyyy1997 · Mar 23, 2014 at 09:49 PM
Fixed it, this code did the trick:
using UnityEngine;
using System.Collections;
public class ExplosionHandler : MonoBehaviour {
private IEnumerator KillOnAnimationEnd() {
yield return new WaitForSeconds (0.167f);
Destroy (gameObject);
}
void Update () {
StartCoroutine (KillOnAnimationEnd ());
}
}
I go the time from the inspector view when I selected the explosion animation in my assets, and then set it to not loop, work's like a charm.
Why is this a better answer than @firestoke's below? (curious)
it's not. unless you like to get hit over the head.
Answer by astracat111 · Jul 07, 2018 at 09:10 PM
Just a disclaimer. myAnimatorReferenceName.GetCurrentAnimatorStateInfo(0).length gets the SECONDS, so if you need the frames like I did just do length * 60f.
P.S - I'm using timers inside of state machines instead of IEnumerators.