The simplest way to fix this is to make the arrow or spear's collider have isTrigger = true
during flight.
A trigger collider detects collisions, but does not resolve collisions by applying impulses to shift the objects apart. You'd handle the collision event in OnTriggerEnter2D(Collider2D other)
instead of OnCollisionEnter2D(Collision2D collision)
.
If you need spears and arrows to have collision resolution at other times, you can set isTrigger
back to false during those times.
Or if you need both behaviours simultaneously, you can do this with two colliders on separate layers, and layer masks filter which collisions get processed. Something like this:
Each character has:
- trigger collider on "hurtbox" layer
- non-trigger collider on "character" layer (interacts with "terrain" layer but not "projectile" layer)
Each projectile has:
- non-trigger collider on "projectile" layer (which interacts with "terrain" and "hurtbox" layers but not "character" layer)
I put the extra collider on the character on the assumption that you're likely to be spawning many projectiles and fewer characters, so this minimizes the expense of the extra collider. It also gives you flexibility to tune the physics of the character for terrain interactions separately from their combat physics - using a more permissive hurtbox for example, or a rounder navigation footprint to avoid snagging on small obstacles.