Trying to unparent an object, than delete it, get a null reference exception.

I’ve got a bullet being trailed with particles, so when it hits something bullet gets deleted, and I want to wait for the particles to disappear naturally before deleting the particle system. So I unparent the particle system, delete the bullet, then attempt to delete the particle system. Sometimes the particle system doesn’t get found when I fire two bullets in a specific situation (one bullet hits a target, the other is naturally destroyed when it’s off screen, both are deleted using the bullets public delete function.) When the bullet hits the target, the target also calls the delete function on the bullet. Is unity handling children of the game object in a way I’m not expecting?

Some code is definitely ragged as I was trying to speed run making a game as fast as possible, the bullet script isn’t really out of the ordinary.
The bullet code:

public class bullet : MonoBehaviour {
    public float bulletSpeed = 1;
    public float bulletDamage = 1;
    // Use this for initialization
    void Start () {
        //gameObject.hideFlags = HideFlags.HideInHierarchy;
    }
 
    // Update is called once per frame
    void Update () {
        transform.Translate(Vector3.left * Time.deltaTime * bulletSpeed);
        if(!GetComponent<Renderer>().isVisible)
        {
            Invoke("delete", 2);
        }
    }
 
    public void delete()
    {
        transform.FindChild("Particle System").GetComponent<bulletSmokeFade>().waitASec();
        transform.DetachChildren();
        GameObject.Destroy(gameObject);
    }
}

bullet Smoke Fade code:

public class bulletSmokeFade : MonoBehaviour {

    // Use this for initialization
 
    // Update is called once per frame
    public void waitASec () {
        GetComponent<ParticleSystem>().Stop();
        Invoke("cleanUp", 0.25f);
    }

    void cleanUp()
    {
        Destroy(gameObject);
    }
}

The situation where the exception occurs:

higher quality MP4: https://i.gyazo.com/35f0a2d91941403f94a4ef62d60f23bd.mp4

1 Like

So, assuming I’m not dumb this afternoon. After a quick glance, it looks like you are waiting for the trail and then, destroying the bullet. There are a couple of ways you could handle it, but two I have off the top of my head are.

  • Having the trail follow the bullet on its own via void Update(), then when the bullet is destroyed, waitASec
  • Having the trail look every lateUpdate if it has a parent, if not, waitASec.

I’m sure there are other ways and maybe better ways but just my two cents.

1 Like

Why isn’t my way working though, those are both a lot CPU-intensive than my current method, I originally was going to do the second one.

1 Like

I was trying to look and see if there was a void OnUnparent but I couldn’t see anything in the reference. In all honesty though. that simple check is not going to have a noticeable impact on performance even in bulk. I’d say you would be safe to use it.

1 Like

I’ll do that for now, thanks for the help, but still wanna know why this isn’t working just for the sake of learning.

1 Like

When I get home later tonight, I’ll take a closer look and break it down.

Why not just turn off the bullet then destroy the whole thing when the particle trail is finished?

That’s true, if the bullet doesn’t need to be destroyed, you can simply disable it. Then destroy it after.

It seems like delete() is being called multiple times. That seems to be the most logical reason for causing this exception to occur.

    void Update () {
        transform.Translate(Vector3.left * Time.deltaTime * bulletSpeed);
        if(!GetComponent<Renderer>().isVisible)
        {
            Invoke("delete", 2);
        }
    }

I believe this may be the culprit. Since there’s a 2 second delay on invoke, Update() is going to keep sending new Invoke()s until 2 secs passes and the first Invoke can kick in.

Add a bool or something to make sure there’s only one Invoke call.