Projectile Spawning and Destroying

I am having trouble destroying a projectile after it reaches its target. The thought process was to find the distance between the target and the current location of the projectile, however at first it was nested in the Input loop, so it wasn’t constantly checking the distance between the two. Now that I have moved it outside of the loop, it seems that it stops checking the distance when a new projectile is Instantiated. I was thinking of checking the distance of all of the projectiles and destroying any that are equal to or less than zero. Any help would be amazing!

void Start()
{
    bulletZValue = Bullet.transform.position.z;
}

void Update()
{ 
    if (Input.GetMouseButtonDown(0))
    {
        GameObject currentBullet = Instantiate(Bullet, ProjectileSpawner.transform.position, Quaternion.Euler(90, 0, 0));
        bulletZValue = +bulletSpeed;
        GameObject currentBulletTarget = BulletTarget;
        currentBullet.GetComponent<Rigidbody>().AddForce(new Vector3(0, 0, bulletZValue) * bulletSpeed, ForceMode.Impulse);      
    }

    dist = Vector3.Distance(Bullet.transform.position, BulletTarget.transform.position);
    if (dist <= 0)
    {
        Destroy(this.Bullet);
        Debug.Log("Bullet Destroyed");
    }


}

private void OnCollisionEnter(Collision other)
{
    Destroy(other.gameObject);
}

}

One issue with the code above is the if (dist <= 0).
Vector3.Distance() will always be positive.
What you probably want is something like if (dist <= projectileRadius + targetRadius).

What’s the purpose behind the distance check? Assuming this projectile has a collider on it with the appropriate layer and so does the BulletTarget, then OnCollisionEnter will do the job anyway, so there’s no need for the distance check unless your projectiles are getting stuck circling around the BulletTarget or something.

Based on line 10, Bullet is your prefab, or at least an original thing you’re instantiating.

Based on line 16 you’re using the prefab’s position to compute distance.

That’s probably not correct.

You probably don’t need to track the bullet, just let it hit and destroy itself with a script.

And why does THIS script have a collision responder function? That seems wrong too…

Finally, about using a super-generic name like Bullet

Instancing and prefabs in Unity and naming your variables:

If you name your public / serialized fields (variables) as simply “thing” then you set yourself up for confusion.

If something is a prefab, name it that, such as public GameObject ThingPrefab; and only drag prefabs into it. Prefabs are “dead things (assets on disk) waiting to be Instantiated.”

If something is already in the scene or you Instantiate<T>(); it in code, then store the result in a properly-named variable such as private GameObject ThingInstance;

Naming is hard… name things WELL to reduce your own confusion and wasted time.

I definitely set myself up for confusion with naming often. I feel like the majority of my problems are from confusing myself. The point of the distance was attempting to do a workaround from checking for a collider trigger. I originally attempted that, but it wasn’t working for me. So I tried to calculate the distance between the bullet and the target and when that number reached 0, destroy the bullet.

Have a think about how that number would ever reach zero, though. The pivot point of the projectile and the target would need to be in the exact same place, which is essentially never going to happen.

I clean up my projectiles in two cases:

  1. They’ve hit something. Collision events / Raycast hits are best for this case.
  2. They’re obsolete. This is usually because they’ve left the play area, or have just been around for too long. I usually just track when each bullet was fired, and clean them up if that was more than X seconds ago.

I also agree that naming is important. If I’ve got a variable that points to a prefab, I almost always call it something like “projectilePrefab”. If I have both prefabs and instances in the same context, I then name them something like “spawnedProjectiles” or “projectileInstances”.

1 Like