Problems with Physics Bullet Collision

Hello,

Currently I’ve given an aircraft guns by spawning physical bullets on mouse click. I have a simple health script and I’ve successfully made the bullet object remove health when it collides with any object that has “UnitHealth” script attached. I have confirmed this works by successfully destroying a truck with the script attached.

There are a few problems, though. First, the bullet seems to not be colliding with the truck if it’s farther than maybe 5 grid squares away. This made me notice that the bullet is also not self-destructing as it should when it collides with the stretched cube I’m using as terrain, which does have a collider. Finally, I am also getting an error message every time the bullet collides with something that does not have the “UnitHealth” script as a component (ie when it collides with the floor)
This is my bullet script:

public class BulletOneScript : MonoBehaviour
{
    public Rigidbody rigid;
    public float speed;
    public GameObject CannonOneMuzzleFlash;
    public GameObject playerCollision;
    public GameObject bulletCollision;
    public float damageDealt;
    // Start is called before the first frame update
    void Start()
    {
        rigid.AddRelativeForce(Vector3.forward * speed);
    }
    public void OnTriggerEnter(Collider collider)
    {
        bulletCollision.GetComponent<Collider>());
        //damage code
        collider.gameObject.GetComponent<UnitHealth> ().Damage(damageDealt);
        Destroy(this.gameObject);
    }
}

Sort of related but not vital for this question - I had to put the spawn points for the bullets pretty far ahead of the visual cannon barrels because when the plane is moving, if the bullets don’t spawn a ways forward then they spawn inside the plane’s collider and disappear. So the bullets despawning on collision does work in that case, I don’t know why they don’t otherwise.
I think I’ve heard that physical bullets are a pain and its better to raycast, but I want the projectiles to have travel speed and drag and gravity. Are my issues with collision just down to unity itself or is there something I can do?

Triggers can only use discrete collision detection which often fails to detect collisions of fast moving objects.

Instead use OnCollisionEnter and set the collision detection mode on the rigidbody to Continuous.

    public void OnCollisionEnter(Collision c)
    {
        c.gameObject.GetComponent<UnitHealth>().Damage(damageDealt);
        Destroy(this.gameObject);
    }

Thank you!

I asked elsewhere and was also shown how to do an if statement to TryGetComponent so that the getcomponent only runs if the object collided with does have the UnitHealth script, but VS is giving me grief about using that statement in OnCollisionEnter.

When I try:

public void OnCollisionEnter(Collider collider)
{

    if (collider.TryGetComponent(out UnitHealth health))
    {
        health.Damage(damageDealt);
        Destroy(gameObject);
    }

    Destroy(this.gameObject);
}

it tells me “The Unity message ‘OnCollisionEnter’ has an incorrect signature.”

When I try

public void OnCollisionEnter(Collision collision)
{

    if (collision.TryGetComponent(out UnitHealth health))
    {
        health.Damage(damageDealt);
        Destroy(gameObject);
    }

it tells me
“Collision’ does not contain a definition for ‘TryGetComponent’ and no accessible extension method ‘TryGetComponent’ accepting a first argument of type ‘Collision’ could be found (are you missing a using directive or an assembly reference?)”

Any ideas for how to keep this solution to the script calling getcomponent on everything it touches and giving an error if the target isnt present?

Collission has a collider property. So just use collision.collider.TryGetComponent.

You can always check these things in the documentation: Unity - Scripting API: Collision

You can also check the available options in your IDE’s auto-complete to see what might be relevant.

Oops! Sorry, I should’ve added the component check. Although it’s common to test the colliding object’s tag to see if it’s of a certain type before accessing a component and so checking for a component’s presence isn’t always necessary.

Alright, looks like I’ve got everything set regarding this particular piece of code. Setting both the bullet and target rigidbody to Continuous detection and that small adjustment to TryGetComponent did work. However I had to disable “is trigger” on the bullet.

Hit detection does work at longer ranges now, but for some reason its way spottier and less consistent than at close ranges. I suppose it’s time to add a debug line to the onCollisionEnter, this may be a separate issue/topic though. Thank you guys for the help

Yep, disabling the trigger is the way to go.

If your target objects are moving then setting the collision detection mode to ‘Continous Dynamic’ on your bullets will be even more reliable. And if your objects are quite small then increasing their collider size will also help.

Final update: Setting the rigidbodies for both the bullet and the target to “interpolate” fixed the buggy detection at range. All set for this issue, thanks again