Sprite Collision Detected But Snapping to Other Side of Collision Shape
My sprite / it's collision shape is colliding with my L and R walls, but if the cursor goes about half way through the shape it snaps the sprite to the other side of it. See here.
I was having a ton of trouble getting my sprite to collide at all, but then saw this post on Reddit. So I applied the "velocity * (1 / delta)
" equation to move_and_collide()
and it collides, but has some weird snapping issues.
extends CharacterBody2D
func _ready():
pass
func _physics_process(delta):
var mouse_pos = get_global_mouse_position()
self.position.x = mouse_pos.x
move_and_collide(velocity * (1 / delta))
I tried making the collision shapes massive but the sprite snaps to the top of it instead of the other side. Not sure if i'm understanding move_and_collide(velocity * (1 / delta))
fully, so maybe knowing what this is doing exactly may help a bit. Took a look at the documentation for move_and_collide()
and the result from velocity * (1 / delta)
is the "motion" which would be the X-Axis positional value?
Regardless, any help is appreciated. Thank you!
Setting the position of a CharacterBody2D directly is not ideal. In this case, the sprite is "teleporting" to the mouse position. If it teleports into a collision, it snaps to the nearest position where its own CollisionShape2D is not overlapping another. The ideal solution is to take advantage of move_and_collide()
.
move_and_collide()
's parameter is a Vector2 which essentially represents the displacement the body wants to move on the next physics update. The body adds this displacement to its position to move, unless a collision is detected along the displacement in which case the body moves until it is just colliding.
When using move_and_collide()
, think about what the displacement should be. This is the difference between where the body wants to go and where it currently is. In your case, this correlates to the difference between the mouse's x-position and the body's current x-position. So, we can calculate this displacement and pass it as the x-component of the vector:
func _physics_process(delta):
var mouse_pos = get_global_mouse_position()
var displacement = mouse_pos.x - position.x
move_and_collide(Vector2(displacement, 0))
Note that the y-component of the vector is zero as we don't want to move vertically.
Now, if we move the mouse beyond one of the walls, a collision is detected along the displacement vector and the body moves up to the wall but not through/past it.