0 votes

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.

in Engine by (15 points)

1 Answer

+2 votes
Best answer

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.

by (13,210 points)
selected by

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.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.