Search Unity

Instant collision checking

Discussion in 'Physics' started by eXonius, May 6, 2016.

  1. eXonius

    eXonius

    Joined:
    Feb 2, 2016
    Posts:
    207
    I have made something like an editor where the user can place bricks. The user can rotate bricks in certain ways. This can be done by entering a rotation value.

    Now If the user inputs a rotation value I want to check if the resulting rotation of the brick and its mesh collider will overlap with the mesh colliders of any other bricks, because if it does I want to refuse that rotation and revert it back to its previous rotation.

    I would like to do all this in the same frame as it would make things a lot easier, because at no point can I allow overlapping bricks. Is there any way to do a simple check for if a pair of mesh colliders intersects?

    All mesh colliders are convex.
     
    Last edited: May 6, 2016
    paternostrox likes this.
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    OnCollisionEnter()?
    If you give him a tag, you can even do:
    void OnCollisionEnter(Collider3D col) {
    if (col.gameObject.tag == "yourTagHere") {
    //Do stuff​
    }​
    }
     
  3. eXonius

    eXonius

    Joined:
    Feb 2, 2016
    Posts:
    207
    I know that gorbit99 but that is not an instant collision check. I would like a function to call that immediately returns true if a collider is intersecting with any other collider and false otherwise.
     
    leni8ec and paternostrox like this.
  4. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    That's as instant as it gets, the same tick as the collision happens, it'll fire. If you don't want to actually read the mind of the user about when he wants to set the rotation to invalid values, then this is the "instant"

    You could also do a Physics.Checkbox with the given rotational values before even rotating the actual gameObject too if you give it an orientation
     
  5. eXonius

    eXonius

    Joined:
    Feb 2, 2016
    Posts:
    207
    No it's not as instant as it gets, unless it's a limitation in Unity.

    When the user enters a rotation value it triggers code to rotate the bricks, however I don't want to rotate them at all if the resulting rotation means they will collide with something.

    If I have to wait for the next collision tick things get a lot more complicated as I would have to remember what rotation values was set before and then rotate them back, which also would look ugly as the user will see the objects bounce back into their original rotation.

    In the same function that updates the rotation I would like to check if the applied rotation causes collision before any frames are drawn, so that I can undo the rotation if that is the case.

    None of this requires any mind reading, just a simple function to call that returns true if two mesh colliders intersect. Problem is Unity doesn't seem to provide any such function.

    Physics.Checkbox doesn’t help because I want to test mesh colliders against mesh colliders, not a box against mesh colliders. If there was a Physics.CheckMesh that'd be perfect.
     
    Last edited: May 9, 2016
    Lapsapnow and paternostrox like this.
  6. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    No, there is no checkMesh, and it seems like you're going to be limited by unity, because this is how collisions work:
    1.Collision check
    2.if collided and unity can fix that (i.e. the object has a rigidbody), then it will apply force
    3.run the other scripts
    4.repeat
     
  7. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    To be clear, this is a PhysX limitation. You will have to estimate mesh collisions by other methods.

    In 2D physics (with Box2D), there is a Physics2D.IsTouching() function that could be used with a temporary collider to see if something overlaps a specific shape. This is the kind of "instant" check OP is looking for, but there is no 3D analog in Unity.
     
    Lapsapnow and paternostrox like this.
  8. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Sorry, my bad

    Because an AABBintersect is really efficient, compared to checking if a mesh is in touch with other one, so basically, until a mod comes here, this question will be stuck
     
  9. Helical

    Helical

    Joined:
    Mar 2, 2014
    Posts:
    50
    Bump, looking for this solution as well
     
  10. Jick87

    Jick87

    Joined:
    Oct 21, 2015
    Posts:
    124
    If you have a Rigidbody on the "brick" you could use Rigidbody.SweepTest. The only limitation there is concerning mesh colliders; They must be convex.
     
    Alex_May likes this.
  11. logicandchaos

    logicandchaos

    Joined:
    May 16, 2016
    Posts:
    26
    Or just figure out another solution.. Like if you animate the rotation.. like rotate it a little at a time then you can stop rotating as soon as you detect a collision, but you shouldn't have to code that if it's a solid collision, I mean not a trigger, if you try to rotate the cube and their is something in the way is should not rotate if you are using physics.

    Another idea I have is what about rotating just the collider, you will not have to keep track of it the parent object will do that for you, if there is a collision you realign the collider with the cube, if there is no collision you realign the cube with the collider. Programming games is a lot of smoke and mirrors, people think they know what is going on or that things happen instantly, but that is all magician tricks.
     
  12. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,555
    If you want raycast hits etc. to work immediately on stuff you've moved around (without waiting for the next frame), you can do this:
    Code (CSharp):
    1. physicsScene.Simulate(advanceBy);
    physicsScene as in from like camera.scene.GetPhysicsScene() etc.. I haven't tested with 0.0f but I use this approach in a custom editor with 0.1f and that solves it.

    Edit: To update immediately without advancing time you can also use
    Physics.SyncTransforms();
     
    Last edited: Aug 25, 2022
    Alex_May likes this.