+1 vote

Godot version: 3.2 Beta 2

Hey folks,

I have a conundrum. I've been using a KinematicBody2D for a player character and using Area2D for obstacles that need to be avoided. When there is a collision, the obstacle emits a signal which in turn triggers the game over sequence.

Now, to move the player I have been using move_and_collide inside _physics_process. This works great, but when I want to reset the player, I've been setting the position manually to get the player back to the spawn point. Here is where the problem starts...

After, resetting the player position, it still collides in the position it was in when it collided originally and the signal is emitted again. Does setting the position directly not affect the physics engine underneath? Does anyone know of a way I could instantly change the position of the object? I'd rather not create a new instance each time if I can help it.

Any thoughts would be appreciated. Thanks :)

asked Dec 1, 2019 in Engine by i_love_godot (346 points)

That should work fine. Sounds like something else strange is going on. Are you somehow moving the body without moving its attached collision shape?

No, I'm definitely moving the KinematicBody2D. The player character is the only Node that I keep between respawns. The level (with the obstacles) is recreated each time by way of a new instance. It is the new obstacles and new signals that fire AFTER the player has been reset. It is very strange.

Ok so I've narrowed it down to having something to do with instancing. This "double" signal emission only happens when a new obstacle is instanced. If I simply leave the original obstacle there, and move the player, one signal is emitted as expected.

I'm still at a loss as to why a fresh Area2D would fire after the player has already been moved out of the way though. I'm either doing something incredibly dumb, or it's a bug, but I don't know how to tell the difference XD

1 Answer

0 votes

This really should work fine. Try changing the physics engine if you can. Or try to, upon collision, disable the collision area of the player, move the player to the spawn point, and then enable it.

answered Dec 1, 2019 by selamba (135 points)

I've tried changing the collision layer bits, but it doesn't affect the outcome. The newly added Area2D nodes still emit their signal as if the KinematicBody2D was still there.

I updated my code to remove the player node and create a new instance each time. It works, but I would prefer to figure out why this isn't working because I am certainly going to run into this problem again at some point.

It is almost like there is a physics ghost. Does anyone know the gritty inner workings of the physics engine? Does it work on a "copy" or "virtual" version of the node, or the node directly?

I'll try and investigate it further with a minimal project. If I discover anything, I'll add my findings here.

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 How to use this Q&A? before posting your first questions.