Search Unity

Resolved Raycast sometimes not detecting a MeshCollider

Discussion in 'Physics for ECS' started by AScaredyCat, Feb 8, 2021.

  1. AScaredyCat

    AScaredyCat

    Joined:
    Dec 31, 2020
    Posts:
    12
    I'm using Entities and DOTs Physics to generate a modular, tile based, terrain system. I generate the entities and their colliders at the start of runtime, then make a grid of the various tiles to make the terrain. The colliders are cached so that I can swap them later as needed. Based on the shape of the tiles, I need to use a MeshCollider type for the most accuracy. I have also made a tool that lets me change tile pieces individually by clicking with the mouse to swap meshes and colliders. This all works perfectly.

    The problem: I am attempting to make a function to automatically generate a terrain feature (like a hill, valley, etc). I am using a loop with Raycasts to probe for individual tiles, and swap their meshes, colliders, and meta data (a custom component) using an Entity Command Buffer, but the Raycasts always fail to find a few of the tiles (the tiles that fail are the same type each time). Interestingly, the method that uses the mouse to modify individual tiles never fails like this, but they both use the same code to make the Raycast checks and the actual changes to the entities. This leads me to believe that there may be a bug with DOTS MeshColliders or Raycasts themselves.

    I have already debugged the colliders and verified the correct ones are assigned when they are first generated or are changed. As mentioned, the raycast used for the mouse to change individual tiles works even for the misbehaving ones, but in a loop the same code always misses those particular tile types.

    Does anyone know of any best practices/ gotchas when working with DOTS MeshColliders or Raycasts? Additionally if anyone has similar experience or reference to official examples that would be amazing! This has been driving me crazy for days now >.<

    If you would like me to post code examples let me know!
     
  2. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
    Hi @AScaredyCat , here are some hints that could help:
    - This sounds like a problem with scheduling, so please double check the timing of your actions - primarily querying and collider swapping.
    - Collision queries use an internal structure called broadphase, which is built by a job scheduled in BuildPhysicsWorld. Collision queries can be performed any time before or after BuildPhysicsWorld, but if you do it before make sure you provide your job handle to BuildPhysicsWorld.AddInputDependencyToComplete(). By default, the broadphase will not get updated until the next physics step’s BuildPhysicsWorld, so all collision queries will return results according to that state (effectively the state after the previous simulation step).
    - There is a way to make StepPhysicsWorld schedule a job that updates the broadphase after current simulation step, at some performance cost – you need to check the “Synchronize Collision World” box in Physics Step component or set PhysicsStep.SynchronizeCollisionWorld to a positive value. If you do that, it is advised to perform collision queries after StepPhysicsWorld or before next BuildPhysicsWorld.

    Hoping this will help, but if it doesn't please share a minimal repro project if possible.
     
  3. AScaredyCat

    AScaredyCat

    Joined:
    Dec 31, 2020
    Posts:
    12
    Thank you for your reply! So I think I may have jumped ahead of my skill level a bit >.<

    Youre probably right about the scheduling issue. Im using the Raycast code example from the Unity Physics documentation page on Collider Queries, and Im calling the code from Update in a monobehaviour on the main thread. In that regard I dont actually know when the query is being run in the frame vs the changes made to the entities. I also dont know if there even is an accessible job handle for me to pass to the physics world in that case.

    If it helps at all, my EntityCommandBuffer uses the EndSimulationEntityCommandBufferSystem to apply the changes to my entities, which does appear after the BuildPhysicsWorld in the entity debugger. I have also tried various other CommandBufferSystems in the frame but I dont think its that simple of a solution. Im assuming that all main thread operations run at a specific point in the frame since monobehaviours are not visible in the entity debugger, so its probably like you said that my queries are happening at the wrong time.

    I have written successful Systems for ECS before, but Im not super experienced with writing Jobified code so that may be the actual issue here. Im assuming its best practice to write something like this in a Job and schedule it for a specific moment in the frame? If so I guess it might be better for me to take a step back and learn more about Job coding before continuing?
     
  4. AScaredyCat

    AScaredyCat

    Joined:
    Dec 31, 2020
    Posts:
    12
    OMG okay, I was able to get it working!

    I took a look at some tutorials for writing Jobified code, and followed the example on the Collider Queries page of the docs for writing a Raycast as a Job itself. It took some work to get some of the errors sorted, but the Raycasts are now done as a Scheduled job as per the docs example, and the function works as expected! Im still unsure of when the actual Raycast is executed in the frame since I did not have to pass the JobHandle to the BuildPhysicsWorld with AddInputDependencyToComplete(). Perhaps there is a way to see when a scheduled task is executed?

    Regardless, I will definitely be Jobifying the rest of my Raycasts so everything is operating on the same Job code. It seems like implementing various tasks as Jobs instead of on the Main Thread is the way of the future for programming in Unity so I guess my ultimate question now is: Should I focus on doing as much as possible in scheduled jobs as a best practice going forward?

    Either way, thank you for giving me some feedback to bounce off of, sometimes thats all we need to learn something new! ^.^/
     
    petarmHavok and steveeHavok like this.
  5. milos85miki

    milos85miki

    Joined:
    Nov 29, 2019
    Posts:
    197
    Hi @AScaredyCat , I'm so glad the hints helped and that you learned some things along the way!

    Yes, I would recommend going further down the systems and jobs learning path, since it's the best way of working in DOTS. Here's some more info that could help:
    - You're right, it's very tricky to control when MonoBehaviors will execute and synchronize that with DOTS systems and jobs. So, it's best to "jobify" whatever you can.
    - Physics samples and Entities docs can be quite useful
    - Forum is a great source of information, we've been discussing job scheduling a lot here.
    - I hope that we will soon be able to roll out a change that will simplify physics jobs scheduling, followed by docs that explain some things many people were struggling with.

    Please feel free to post again if you bump into new problems.

    Edit: Forgot to mention, you can see the job execution timeline when you select a frame in the profiler (ctrl + 7).
     
    Last edited: Feb 9, 2021
    AScaredyCat likes this.