2D collision with mouse controlled player

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By eliasreid

Hello, I am a Godot beginner. I’m working on a fairly simple 2D game, which has a player that is controlled directly by the mouse, and enemies that travel across the screen that should damage the player on contact. I’m trying to figure out the best way to detect simple collisions, like enemy contact with the player. I don’t want the player and enemy to actual interact / bump into each other, just want to damage the player.

I tried using Area2Ds for both the player and child (circle collision shapes). I was able to set up the collisions masks and get the signal as expected. Seemed to work well until I moved the player very quickly with the mouse, passing right through enemies. This makes sense, as the player’s area could jump over the enemy without spending a frame on top and never overlap.

From what I can tell, PhysicsBody nodes should be more suited for this type of continuous collision detection. But based on the documentation, I shouldn’t be updating their positions directly (which I am violating by setting the Player’s position to the mouse position).

Does anyone know of a simple solution for this in Godot? I’m sure I could hack something together, but want to use the engine built in features as much as possible.

:bust_in_silhouette: Reply From: jgodfrey

You’re right - the problem is likely that at frame n, the player is on one side of an enemy and on frame n+1, the player is on the other side of the enemy, and even though their paths crossed, they never actually collided.

One typical solution to this problem is to add a Raycast2D to your scene, and use it (in every frame) to cast a ray between the player’s previous position and the player’s current position. If that ray collides with an enemy, do damage to your player as there should have been a collision.

Thanks for the idea! With that in mind, I think I might as well interpolate from frame n to n+1, basically turning the player into a capsule collision shape that elongates with its velocity. That way I won’t miss cases where the player’s edge just grazes an enemy.

EDIT: The issue was actually mostly alleviated by moving the update position code for the player and enemy from _process to _physics_process. Probably should have been there in the first place.

eliasreid | 2020-03-01 03:46