Physics.set_listener not working?

I want to start using physics.set_listener, but once I add the code as shown on the example in the manual, all my objects are still getting their regular collision messages, and nothing is printing from the listener function.

I have a game object with a “main.script” on it which is where my game starts, and this line is in my function init(self) function, it’s definitely being run because I put a breakpoint on it and it hit.

physics.set_listener(physics_world_listener)

But breakpoints are not being hit on any of the lines below and nothing is being printed. I would expect trigger_event to be hit and I would also expect all the behaviour in my game to break, since according to the manual, objects don’t receive messages once you activate the listener;

local function physics_world_listener(self, event, data)
    if event == hash("contact_point_event") then
        -- Handle detailed contact point data
        pprint("contact_point_event: "..data)
    elseif event == hash("collision_event") then
        -- Handle general collision data
        pprint("collision_event: "..data)
    elseif event == hash("trigger_event") then
        -- Handle trigger interaction data
        pprint("trigger_event: "..data)
    elseif event == hash("ray_cast_response") then
        -- Handle raycast hit data
        pprint("ray_cast_response: "..data)
    elseif event == hash("ray_cast_missed") then
        -- Handle raycast miss data
        pprint("ray_cast_missed: "..data)
    end
end

I’m using Defold 1.6.4

How did you add the listener?
Do you get a printout / breakpoint at that place?

Yes, it’s the first code snippit I put in my post.

Here’s my full init function

function init(self)
	-- Add initialization code here
	-- Learn more: https://defold.com/manuals/script/
	-- Remove this function if not needed

	print("Hello world")
	msg.post("/camera#camera", "acquire_camera_focus")
	msg.post("@render:", "use_camera_projection")

	msg.post(".", "acquire_input_focus")

	physics.set_listener(physics_world_listener)
	
	--msg.post(player_join_screen, "load")
	msg.post(level_race, "load")

	game_state = GameState.GAMEPLAY
	
end

Make sure you declare physics_world_listener above the init() function, otherwise it’ll be nil (which disables the physics listener).

2 Likes

Oh yes…

Ok here’s roughly what I have, and there’s still no effect. This is how I’ve been calling functions in my other scripts;

local physics_world_listener
...
function init(self)
   ...
   physics.set_listener(physics_world_listener)
   ...
end

physics_world_listener = function(self, event, data)
   ...
end

What if you print(physics_world_listener) in init?

I get this, it appears to be a different value each time.
DEBUG:SCRIPT: function: 0x025c06ffb740

Ok well, it works in a blank project, so no idea what’s happening in my project that makes it not work. I even tried just making the function local above the init function exactly as it appears in the example, and it still doesn’t work in my project.

I’ll keep picking away at it…

Ok it seems if you load a new collection proxy, that involves re-creating the physics, so you have to do this script after that collection proxy has been loaded.

1 Like

Every collection has its own physics world.
So, yes, you should set the listener for each physics world separately from inside the physics world itself.

5 Likes

Makes sense, but it should say that in the listener manual page.

1 Like

It might be good to make mention of it there. Though to the manual’s credit - like a lot of good manuals, the info is all there, just not in the place you might expect to find it depending on what mindset you’re coming from or what you’re doing. I don’t think it’s anyone’s fault really.

The “Collection proxy” page makes mention of a “new physics world” being created.

To fit the game objects and their components the engine allocates the memory needed for the whole “game world” into which the contents of the bootstrap collection are instantiated. A separate physics world is also created for any collision objects and physics simulation.

1 Like

The API reference for the function states that the function “sets a physics world event listener”.

And the manual page also mention the physics world:

“This function takes a callback as its argument, which will be called with information about all physics interactions in the world”

We could perhaps add a special mention that the function must be called from within the physics world? We could also add a link to the collection proxy page where the concept of individual physics worlds are mentioned?

2 Likes

I added this info into manual Add info about collection proxies by AGulev · Pull Request #418 · defold/doc · GitHub
will be on site in 10 minutes or so

UPD: Collision events in Defold

5 Likes