Using physics.set_event_listener() to resolve collisions

Is this the correct way to resolve kinematic collisions using event listener?

local function physics_world_listener(self, events)
	local id = go.get_id()
	for _, collisions in ipairs(events) do

		local collision
		if collisions.a.id == id then
			collision = collisions.a
		elseif collisions.b.id == id then
			collision = collisions.b
		end

		if collision then
			if collisions.distance > 0 then
				local proj = vmath.project(self.correction, collision.normal * collisions.distance)
				if proj < 1 then
					local comp = (collisions.distance - collisions.distance * proj) * collision.normal
					go.set_position(go.get_position() + comp)
					self.correction = self.correction + comp
				end
			end
		end
	end
end

I’m asking because in this thread @aglitchman correctly points out that the max_time_step shouldn’t affect physics that use use_fixed_timestep.

But, with the code in the above example, the physics experience tunneling even with use_fixed_timestep set to true.

If I instead resolve the collision from a message, (like in this example) there is no tunneling.

Does this mean that events received with physics.set_event_listener() are triggered during the normal update(), rather than fixed_update()?

I think it’s more likely that there is something wrong with the code above, but here is a minimal example just in case.

Archive.zip (4.2 KB)

1 Like

I decided to test this. It does look as if the listener events are always fired after update(), even when use_fixed_timestep is set.


PhysicsListenerFixedUpdate.zip (3.8 KB)

This means that if you use use_fixed_timestep, and want a stable physics simulation, you have to use messages, rather than physics.set_event_listener().

I’m not sure if this is a bug, or intended behaviour?

2 Likes

I have a bug in my game that seems to be linked to physics events sometimes arriving too late because physics.set_event_listener() is used.

Before I go ahead and refactor my code to use messages instead of callbacks, does anyone know the answer to the question above?

Try using the deprecated physics.set_listener. For the “new” set_event_listener, they added grouping (batching) of events and seem to have forgotten that physics can work in fixed steps.

The fix is simple, I think, - this condition should also be in the following function for fixed update:

3 Likes

Please create an issue on GitHub. I think they will fix it quickly. It’s a “quick win” type of issue.

1 Like

WOW!

Using physics.set_listener() works and fires on fixed_update(). Thanks so much!

I took the liberty of adding a Github issue for this:

3 Likes