Separate callbacks behaviour for multiple rids created via server (PhysicsServer2D or NavigationServer2D) in the same script

Godot Version

4.6.1

Question

I want to create multiple istances via NavigationServer2D and PhysicsServer2D but managing the callbacks from NavigationServer2D.agent_set_avoidance_callback() or PhysicsServer2D.area_set_monitor_callback() differently for each rid.

I have a script that handles multiple units using godot’s servers like this:

void Ready()
{
for (int i = 0; i < 1000; i++)
{
        Rid agent = NavigationServer2D.AgentCreate();
        NavigationServer2D.AgentSetMap(agent, GetWorld2D().NavigationMap);
        NavigationServer2D.AgentSetMaxSpeed(agent, 100f);
        NavigationServer2D.AgentSetRadius(agent, 4f);
        NavigationServer2D.AgentSetAvoidanceEnabled(agent, true);
        NavigationServer2D.AgentSetAvoidanceCallback(agent, new Callable(this, MethodName.OnSafeVelocityComputed));

        Rid area = PhysicsServer2D.AreaCreate();
        PhysicsServer2D.AreaSetSpace(area, GetWorld2D().Space);
        PhysicsServer2D.AreaSetCollisionLayer(area, 0b00000000_00000000_00000000_00000001);
        PhysicsServer2D.AreaSetMonitorable(area, true);
        PhysicsServer2D.AreaSetCollisionMask(area, 0b00000000_00000000_00000000_00000000);
        PhysicsServer2D.AreaSetMonitorCallback(area, new Callable(this, MethodName.OnUnitAreaCallback));
}
}

public void OnSafeVelocityComputed(Vector2 safe_velocity) { }

void OnUnitAreaCallback(PhysicsServer2D.AreaBodyStatus status, Rid area, int id, int body_shape, int self_shape) { }

I would like to know each time OnSafeVelocityComputed() or OnUnitAreaCallback() which rid called the method.

Use Callable::Bind() to bind an additional id argument to the callable.

Can you please show me the full implementation? I can’t imagine the correct syntax.

Look at the reference for the Callable class.

Hm, it looks like Bind() is not implemented in C#. Docs say to use lambdas instead:

Or just implement this particular thing in GDScript.

1 Like

If I implement it in gdscript I would loose the performance gained with C# though. Maybe it should be something to work on for the engine in the future.

Not necessarily. Try to implement and then measure the performance by profiling it in both cases. You may be pleasantly surprised.

You can only implement the callback wrapper in gdscript that calls your main C# code.