Obtaining PhysicsWorldSingleton in OnCreate InvalidOperationException: GetSingleton<Unity.Physics.Ph

So basically when I try to obtain PhysicsWorldSingleton in one of my systems OnCreate like this:

public void OnCreate(ref SystemState state)
{
    PhysicsWorldSingleton pws = SystemAPI.GetSingleton<PhysicsWorldSingleton>();
}

I get:
InvalidOperationException: GetSingleton<Unity.Physics.PhysicsWorldSingleton>() requires that exactly one entity exists that match this query, but there are none. Are you missing a call to RequireForUpdate()? You could also use TryGetSingleton()

It does not throw exceptions when I obtain it in OnUpdate.
Are there some rules regarding usage ?

The singleton is created in another systems oncreate

If your system is created before this system then it won’t exist yet

You can use [CreateAfter(T)] to get around this however I’m not sure why you need the singleton in oncreate considering the physics world will be empty until an onupdate at least.

2 Likes

I have got navigation grid and I wanted to populate it using static collider from the physics world.
I wanted to do it quite early so units can be placed in proper cells.

Do you know how to “catch this moment” when all physics is ready and all things on my scene are loaded ?
So I can run my system right after it ?

You can add your system to the AfterPhysicsSystemGroup.

1 Like

I have tried this one and some other groups also.

Inside OnCreate(){…}
This:
PhysicsWorldSingleton pws = SystemAPI.GetSingleton();
Is properly returned.
Unfrtunately
pws.CollisionWorld.Bodies
Is empty.
It is populated when I check it during OnUpdate.

Is it that physics world is populated with bodies during it’s OnUpdate ?

I suggest you open the jobs section in the profiler. There you will see the jobs launched by the different systems and then processed with specific dependencies between them.
For example, there you will see the BuildPhysicsWorld system which launches among others the two CreateRigidBodies jobs for creation of the dynamic and static bodies. These two jobs fill up the CollisionWorld.Bodies array.
In the profiler you can see them being run.
While these run you can’t yet access the collision world.

If you want to access it, from your system you need to create a job that references the CollisionWorld and schedule the job using the system’s state.Dependeny handle in OnUpdate.

For plenty of examples of how this is done I suggest you have a look through the demos in the PhysicsSamples project.

1 Like