I am spawning multiple objects in a tight loop. The problem I am running into is that a ray cast from one object doesn’t appear to see any of the objects created prior to it in the same loop.
Is there a way explicitly force the PhysicsScene to be updated during the loop?
EDIT: Note that the obvious, wait for the next fixedUpdate isn’t an option as this is an Editor tool.
As soon as you add an object you can perform physics queries on it. Note that if you’re adding objects to a specific scene then you need to perform physics queries on that scene and not use the global physics queries on Physics / Physics2D types as they operate on the default physics scene only. but instead use the ones on the PhysicsScene type.
If you’re expecting overlapped colliders to be moved out of the way or have physics callbacks as you add each then I would urge you to not do that as it’d get very expensive.
Spawn Object 1
Spawn Object 2 Above Object 1
Raycast down from Object 2. Ray does NOT see Object 1 like it should.
If those two actions take place as separate actions initiated by the user, thus allowing a FixedUpdate between them, then the ray sees the other object. If it happens in code during a loop, thus not allowing FixedUpdate to happen, the ray does NOT see the other object.
I was in the middle of editing my reply so take another look. Ensure you’re querying the scene in question that you’re adding objects to. Queries should work immediately after you’ve added the physics components.
I just got it confirmed that 3D physics components added to the scene are available to be queried immediately. Apparently it has been that way since Unity 5.0.
I am therefore not sure what is going wrong in your case. Maybe a code snippet would help, maybe not. Maybe try a simple case of adding a sphere then instantly seeing if you can query it.
Ok this does appear to work as expected in a simple test case, so I’m at a loss as to why it doesn’t in the actual code. I will need to dig into it more
If I retrigger the spawn & cast, then it will see 1, then 2, etc in the debug log. So each run through it only sees the previous spawns, not the current one.
NOTE: I am drawing a DebugRay in the scene to visualize the Raycast so I can verify it is indeed pointing properly:
My guess here is that the collider is not updating immediately when the spawned object moves as a result of the parenting with worldPositionStays false.
That’s because by default on new projects AutoSyncTransforms is off. You should try to avoid having this setting on for performance reasons. You can perform a manual SyncTransforms but this has a performance cost too when you call it but it might not be an issue in your case. Note there’s more detail on the above doc links.
In most cases it’s best to set the transform prior to adding physics components if you want to immediately query them. In the case of prefab instantiation, I’d need to check, but maybe Object.Instantiate sets the transform prior to adding in the other components or activating it but I suspect that might not be the case.
Could this perhaps be added to the Raycast documentation? This cost me over a dozen hours of development time looking for solutions, workarounds, or known issue reports. Simply state that a ray will not hit an object that has moved until the next physics update, but that transforms can be synced manually with SyncTransforms(). I’m using raycasting to set up a puzzle, and the alternative do raycasting in Start is complex logic through several calls to FixedUpdate.
This is not specific to Raycast. If you modify a Transform, it ONLY modifies a Transform, it doesn’t modify ANY other component. Should this be added to every single method and property on both the 2D or 3D physics systems that perform any reading of any kind? No, of course not.
The problem is that you’re using the Transform system as the authority on the pose when in-fact it’s the Rigidbody that WRITES to the transform and acts as a proxy to it for you so it’s the other way around. You should use the Rigidbody API to cause movements. The whole point of a Rigidbody is to move around using physical motion and update the Transform system.
If you are moving stuff in physics by driving the Transform you’re doing it incorrectly.
If you’re using SyncTransforms, you’re using a method that is only there for bad practices and legacy behaviour.