godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.58k stars 21.09k forks source link

changing collision shape dynamically in _process delays detection #44348

Open chucklepie opened 3 years ago

chucklepie commented 3 years ago

Godot version: 3.2.3

OS/device including version: Linux

Issue description: I will provide test code if this is thought to be a bug (as it will take a while to create small sample).

I have an object (a laser beam) that starts small and gets bigger over the course of a few seconds. As it gets bigger (there is no scaling involved, this is purely a sprite/pixel visual thing), I am changing the area2d collision shape dynamically (in _process) every frame until it reaches a set size then I leave it at it's maximum size and make no more changes, i.e. this is the code while resizing

collision.shape.extents.x=length

When at the largest size and not resizing, collisions happen exactly as expected. However, during this resizing phase there is a large delay in the collision detection triggering. Below is when the laser triggered hitting the object, as you can see, it's way past.

image

However when 'visible collision shapes' are enabled, firing at the same point, collision happens instantly as expected. Observe:

image

The rectangle between the player and the object (the laser beam) has triggered exactly on target. This also shows that the collision box is fine and in the correct location and size in the first example.

I am getting 60fps and there is no performance issue and this delay is not just a few frames it is maybe half a second.

So, I know the collision shape is fine but something is only triggering it properly during changing extent when debug is on.

I have tried a ray that I resize in the same way and that works fine, but I cannot use a ray due to requiring area collision boxes.

Am I missing something that 'view collision shapes is doing' or is there some kind of known extent resize issue with Godot?

Minimal reproduction project: If this is seen to be a possible bug (i.e. just just a coding error) I will provide full code.

chucklepie commented 3 years ago

ello, I've done more testing and what seems to fix it is one of two things:

  1. I move my code that resizes the collision shapes from _process to _physics_process, OR
  2. I reduce my SPEED constant to below 200 (x+=SPEED*delta)

Note,

  1. I'm getting a solid 60fps so would expect process and physics to be called the same
  2. SPEED at 200 takes over half a second from point of collision to actual detection so I doubt it is speed related that much
  3. As mentioned, turning on debug collision shapes fixes everything without the two things above
Demindiro commented 3 years ago

I'm unable to reproduce this. Using _physics_process the collision happens (and is detected) exactly after 9 frames regardless whether collisions shapes are visible or not. With _process, it happens after 11-12 frames consistently. I also tried toggling Sleeping & Can Sleep on the RigidBody but it doesn't make any difference.

collision-detection-delay.zip

chucklepie commented 3 years ago

Ok. I'll try and get a demo project. I'm not using a rigid body or a kinematic body.

chucklepie commented 3 years ago

@Demindiro and anyone else:

Download my attachment and you need to do the following please to see it failing:

  1. run the game, press SPACE and it will breakpoint when the laser hits the object OK, F12 to continue
  2. press the right arrow until the player character is somewhere near marker I've placed (at collision 'growing stage')
  3. repeat the above and it is all OK

Now, go to line 35 in player_bullet_laser.gd and switch from _physics_process() to _process()

  1. repeat the above and at normal distance it is fine but at the closer distance it hits far past
  2. Turn on view collision boxes if you wish to ensure they are in the right place and size

Note the distance between the two hits in physics/process is about 128 pixels. At speed of 360 this is 6 pixels per frame. Which means even taking into account a few frames dropped, it is taking 21 frames before it registers a collision after it should. I think. Which is way beyond normal, and regardless it is running at 60fps with no frame drops to even consider it is because it is 'too close'.

nw_collision_test.zip

When collision shape is not growing with _process or _physics image

With _physics image

With _process image

pouleyKetchoupp commented 3 years ago

I can reproduce the issue in 3.2.3 and in 3.2.4 beta 5, but it doesn't look like having debug collision on or off affects the behavior.