4ian / GDevelop

🎮 Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.
https://gdevelop.io
Other
10.81k stars 848 forks source link

Physics behavior not tracking collisions properly. #4009

Closed HelperWesley closed 2 years ago

HelperWesley commented 2 years ago

When collisions happen between frames the physics behavior doesn't count them as collisions, and therefore developers who expect a sound effect or value to change upon collision will be sorely upset.

To Reproduce

Just play the game at 20 min fps and 20 max fps and compare it to 60/60. There will be missing counts.

Plinko.zip

HelperWesley commented 2 years ago

@AlexandreSi

4ian commented 2 years ago

We'll fix that by keeping in memory contacts (that's the term used by the physics engine) for the frame, so we can have:

tristanbob commented 2 years ago

Tagging these so we can update/close when done:

https://github.com/4ian/GDevelop/discussions/3805

https://github.com/4ian/GDevelop/issues/3853

tristanbob commented 2 years ago

We'll fix that by keeping in memory contacts (that's the term used by the physics engine) for the frame, so we can have:

  • a condition "X is currently colliding with Y" (the existing one, renamed)
  • a new condition "X is currently or has just collided with Y" (the new one, so you're 100% sure you're not missing a bounce).

We should consider this new feature while we are selecting wording for collision conditions:

https://github.com/4ian/GDevelop/issues/3929

Existing conditions:

ObjectA is colliding with ObjectB = Objects are colliding this frame

New conditions:

ObjectA started colliding with ObjectB = Objects were NOT colliding last frame, but now they are. ObjectA stopped colliding with ObjectB = Objects were colliding last frame, but now they are NOT.

Perhaps we can add a boolean parameter to all of these conditions?

Include collisions that occurred between frames

I think that setting should be enabled by default.

Silver-Streak commented 2 years ago

You probably will need some sort of wording (or detail on the wiki) that explains that any logic associated with it will still only occur during the "current" frame, regardless if the collision occurred mid-frame.

Unless you're all reworking how the engine processes logic entirely 😆

tristanbob commented 2 years ago

@AlexandreSi came up with some use-cases (A, B, C) to analyze:

Let's imagine we are working on 4 frames:
   |Frame0           |Frame1              |Frame2               |Frame3
A.                          < start...................end >
B.                      < start....end >
C.     < start........................................end >
D. .........................end >     < start.........end >

Here is what I am proposing:

ObjectA IS colliding with ObjectB = Objects are colliding this frame

Case A: Frame 2 Case B: Frame 2 Case C: Frame 1, Frame 2 Case D: Frame 0, Frame 1, Frame 2

ObjectA STARTED colliding with ObjectB = Objects were NOT colliding last frame, but now they are.

Case A: Frame 2 Case B: Frame 2 Case C: Frame 1 Case D: None

ObjectA STOPPED colliding with ObjectB = Objects were colliding last frame, but now they are NOT.

Case A: Frame 3 Case B: Frame 2 Case C: Frame 3 Case D: Frame 3


EDIT: Removed the boolean parameter "Include collisions between frames" EDIT2: Added case D