The Art of Projectiles

We got two paths that can be taken ( correct me if there is more )

  • the projectile is a trigger → OnTriggerEnter
  • the projectile is not a trigger → OnCollisionEnter

OnTriggerEnter is imo not valid for projectiles that are meant to explode at a wall sometimes up to a meter in the wall. I played around with an additional raycast that is supposed to find the exact wall as soon as OnTriggerEnter happens but the general positioning of the object when OnTriggerEnter happens is far too unreliable.

OnCollisionEnter means the object is physical and bounces off walls. This can be dealt with by making it kinematic on Impact, so it works for single projectiles that hit something and then disappear.

How would you make a projectile, that is supposed to pierce the first enemy?

What i would need is collision that is as exact as OnCollisionEnter but not changing/blocking the projectiles movement.

Raycast looks good for your case. Or if you like Colliders, using a collider with a rigidbody using interpolation may help,

Interpolation has no effect on physics, it’s purely a visual Transform thing.

OnTriggerEnter is just a callback so it’s kind of an odd statement TBH. Specifically though, Triggers don’t stop things because they don’t produce a collision response because, as their name suggests, they are only a trigger or notification. So yes, you’ll always be partial touching or completely inside a trigger when you get a callback.

If you need to know a future position where you’ll start to intersect a collider (trigger or not) then a physics query (raycast, shape cast etc) will tell you that. Nothing new there though.

Note: OnCollisionEnter isn’t guaranteed to give you the exact point either if you’re using discrete col-det and not continuous. In the end, contact points are where the physics will apply an impulse (or not) to keep colliders separated.

1 Like

Mistaken it for the “Collision Detection” Rigidbody param. Thanks for the heads up.

2 Likes

@MelvMay Thanks for clarifying!

What would be the way to go if i need precise collision ( as i need the exact points like with OnCollisionEnter ) but i don’t want the projectile to stop but rather go through multiple targets? I feel like i need a mix of both trigger and collider behaviour. Hope my point comes across.

you may run any number of raycast calls as needed. For example, if in a given frame your bullet will move 2.5 units ahead, and happened to hit a target along the way, you may re-call another raycast call, starting from where the bullet hit previously (or maybe very very little ahead to not repeat the collision by mistake)

Dont know if my explanation is good. Makes sense?

2 Likes

It does. It is basically a selfcalculated continued collision detection: i imagine it would work really well against walls and other slow objects but collision between two fast moving objects this way would require me to check if the movement rays of each two of these did cross since the last frame.

I’m trying to get a feeling for what is right and useful for different scenarios here, so this helped me quite a bit with building my mental model here.

Just as a side note, instead of calling Raycast() multiple times like Zimbres suggested, you can call RaycastAll to get all colliders within the specified distance that are affected by the raycast.

Note that calling RaycastAll will give you the convenience of creating an array for results but will also mean you get one on each call and it’ll get thrown at the GarbageCollector so terrible for overall performance. Never use the “All” suffix calls, just use the calls without any suffix. Every single physics query has an overload that allows you to return all sorted results into an array or List.

1 Like

Good to know, thanks @MelvMay

1 Like