#better collisions for fast moving projectiles?

1 messages · Page 1 of 1 (latest)

hexed sky
#

I have been making a top down shooter for a few days but have been plagued with weird collisions on these fast moving bullets. sometimes bullets will just go through something but will still collide, just after it's fully inside of the hitbox. I set the hitbox of the bullets to be slightly in front of the bullet sprite itself but that has only slightly helped. any methods for better collisions? the bullet itself is just a character body 2d with an area 2d attached that deletes itself when it enters a hitbox or some other collision body.

hexed sky
#

here's the hitbox code as well for the bullet

dreamy leaf
# hexed sky I have been making a top down shooter for a few days but have been plagued with ...

"bullet through paper" problems like these are unavoidable with raw physics and very fast-moving-objects. One solution would to shoot a raycast (or shapecast if your bullets are very big) forward from the bullet every physics step, check if there's anything the bullet would collide with next frame, and then move the bullet to the collision spot that physics step instead of fully inside the hitbox

hexed sky
#

okay, got it. in my code, if I want to set the velocity to make sure that it will stop ahead of the raycast's collider, how would I code that? this is what I have so far.

#

actually made a mistake in the target pos code, meant to make it just change the x value not the whole vector

inner lantern
#

Idk if a 2D raycast's target position is global, but if it isn't you should change it to:

raycast.target_position = to_local(global_position) + velocity * delta

hexed sky
#

updated my code again, here's what I have so far. the reason for the abs() was because the raycast was only ever pointing in the +x direction for some reason. it kind of works, but for some reason you can still see the bullet entering the object and not stopping in front of it.

inner lantern
#

Do you still have tunneling issues?

hexed sky
#

after I changed the code

#

also I didn't show it but it's a lot more apparent when shooting at actual enemies

inner lantern
#

I realize you aren't calling on_hit() when the raycast is colliding, how is the hit detection working right now?

#

Oh you are using an area hitbox

hexed sky
#

yeah

#

i could hook it up to the raycast tho

inner lantern
#

You can just call on_hit() and pass in the collider when the raycast is colliding

hexed sky
#

true

#

i tested that and it works but the bullet looks like it's stopping way before whatever it's hitting

#

which isn't a huge deal since ill probably add impact effects later but still

inner lantern
#

So i actually do my project's projectiles differently; they hold a prev_pos variable, and instead of raycasting ahead, it raycasts from the prev_pos to the current_pos

#

prev_pos just being the position the bullet was the previous frame

#

I think that would get rid of the bullets looking like they collide early

hexed sky
#

okay, ill try that

inner lantern
#

You can make sure prev_pos holds the last frame's position by updating it last in physics_process, and having your functions run before it

hexed sky
#

alr

#

so something similar to this?

inner lantern
#

yes but i realize you can get rid of current_pos as a variable and just use global_position

#

and make sure to use to_local() for the target_position

hexed sky
#

now it just wont collide with anything

inner lantern
#

try making the raycast top_level

hexed sky
#

still nothing

#

kinda weird, can't even see the raycast even though I have visible collision shapes enabled

#

probably just cause it's too small or something

inner lantern
#

scratching my head rn

#

i feel like it has something to do with the raycast's local position and converting its global_position locally

hexed sky
#

maybe

#

just tried "raycast.to_local" but still nothing

#

weidly it looked like the raycast was just firing up for a second

inner lantern
#

i'll send you my projectile script, it's 3D but you should be able to convert it

hexed sky
#

somehow prev pos and global position are the same

#

just did some print statements and both are the exact same

inner lantern
#

ah

#

try putting prev_pos = global_position into the else statement

hexed sky
#

doesn't look like it changed anything

inner lantern
#

my script is too long to send let me cut some stuff out of it

inner lantern
hexed sky
#

yeah idk

#

i understand ur code and it honestly looks like it would have the exact same functionality

inner lantern
#

try storing all the raycast related code into a single function, like handle_ray()

hexed sky
#

okay

#

did that and it looks like the positions are different

#

however still not colliding with anything somehow

inner lantern
#

you could try using the physics server instead of a raycast

#

i suspect it's some jank with the raycast's position inheriting the projectile's and how it's being updated constantly in physics_process

#

using the physics server would mean just checking between two positions

hexed sky
#

okay

#

let me try that

#

this is what i have

#

still nothing

inner lantern
#

how big is the difference between prev_pos and global_position?

hexed sky
#

the positions with no name are the global

inner lantern
#

yea that seems like its working wtf

#

is the ray being blocked by the projectile's body? since its a characterbody

hexed sky
#

nah, it doesnt have a collision shape

inner lantern
#

im lost man

#

hopefully someone else knows whats wrong here

hexed sky
#

okay then

#

im gonna leave this here for now and just set up the old system again

#

i feel like im losing my mind

#

i was literally watching other top down shooters have fast moving projectiles with collisions that dont suck

#

it feels like it should be pretty easy but whatever

sterile wolf
#

Rigidbody2D has continuous collision detection support that should handle this out of the box. However, I don't see an option for that on CharacterBody2D. Is there a reason you require that particular class for your projectiles?

The docs for the continuous CD are here:

https://docs.godotengine.org/en/4.4/classes/class_rigidbody2d.html#class-rigidbody2d-property-continuous-cd

hexed sky
#

@inner lantern @sterile wolf just wanted to update this to say I have found an okay solution right now. I used the raycasting method to get more accurate collisions however visually the bullet stops much before whatever it's going to hit. To answer your question, the reason it was a character body was because I was originially using the move and slide function to move the bullet, although now I don't use that for movement. I would use rigid bodies, but arent they expensive to instantiate / have lots of in the scene?

inner lantern
#

If you're going for a bullet hell style amount of projectiles, (1000+) id make a ProjectileManager class that will make each projectile just some data (position, velocity, transform) and update them in a for loop

hexed sky
#

Im not super sure if it's gonna be a bullet hell kind of game, was more aiming for something like hotline miami or otxo

inner lantern
#

If there won't be many projectiles at once, your implementation will work just fine💯

hexed sky
#

Alr