Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Switching RigidbodyType2D triggers OnTriggerExit2D

Discussion in '2D' started by jaeschkeshaun, Aug 2, 2023.

  1. jaeschkeshaun

    jaeschkeshaun

    Joined:
    Oct 26, 2020
    Posts:
    6
    Hello this is a major issue I'm having, exactly as the title says. I have an object with a Rigidbody2D that is inside of a trigger and when I change the RigidbodyType2D it sets off OnTriggerExit2D. Unexpected interaction IMO. Is there a way to change this behavior? If changing RigidbodyType2D is bad practice or there is no way to change the behavior? I can find a work-around but knowing if there is another solution first would be nice.
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    When you change the type, what are the two body types that were interacting before and what are they after i.e. are you sure those body-types can come into contact?

    What should trigger the exit is that there are no longer any contacts. Changing the body-type itself doe nothing beyond just changing the body-type.
     
  3. jaeschkeshaun

    jaeschkeshaun

    Joined:
    Oct 26, 2020
    Posts:
    6
    It starts with a GameObject, "Level", with a PolygonCollider2D that encompasses my whole level, with isTrigger set to true, and another GameObject, "Ball", with a CircleCollider2D, and a Rigidbody2D, with RigidbodyType2D set to Dynamic.
    The level has no Rigidbody2D because its just a collider to detect if the Ball is in the level, as well as to keep Cinemachine confined.

    When I change the RigidbodyType2D of the Ball to Static, while still within the Level's collider, a script component of the Level runs OnTriggerExit2D.

    The behavior seems unintended unless its an issue detecting the collision from the Level's end and not the Ball?
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    Static do not contact Static because they never move so there'd be no point. You get an exit because there are no longer any contacts.

    Also, this type of single Static collider covering the whole level is terrible for performance unless you carefully limit what it can contact by layer. A better way is to perform an area physics query when you need to know what is there rather than asking the physics to calculate contacts with everything in the scene (that whole region) each time the simulation steps.
     
    Last edited: Aug 2, 2023
    jaeschkeshaun likes this.
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    If you absolutely must do this kind of interaction (not sure why) then you can add a Rigidbody2D to your "level" set to be Kinematic and enable the Rigidbody2D.useFullKinematicContacts option. Typically Kinematic do not produce contacts with other Kinematic or Static but with this option on, you get contacts as well as callbacks.
     
  6. jaeschkeshaun

    jaeschkeshaun

    Joined:
    Oct 26, 2020
    Posts:
    6
    Ah okay that makes sense. Thank you!

    The ball is the only dynamic RB in the scene, therefore there shouldn't be many issues, in regards to excessive collision detection, correct?
     
  7. jaeschkeshaun

    jaeschkeshaun

    Joined:
    Oct 26, 2020
    Posts:
    6
    I don't imagine I'll have to do it that way. I might try as a very temporary bad workaround. The game is very barebones overall either way; Any other RBs I have right now are static.
     
    MelvMay likes this.
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    Well if you're using a level-wide collider to detect the player then it's still a bad thing to do. It's not clear what its used for but if you're happy with it then that's fine but maybe I can advise a better way of doing it if I understood what it's used for.

    I only caution this because I've seen this done so many times and then a dev adds something complex like a TilemapCollider2D with thousand of tile shapes and the physics still has to discount those shapes so whilst fast, it's problematic in many cases. :)

    Physics.OverlapArea also suffices depending on what you're detecting and you can do it when you want to.

    Either way, good luck, hope this helps.
     
  9. jaeschkeshaun

    jaeschkeshaun

    Joined:
    Oct 26, 2020
    Posts:
    6
    I was just using it as an easy way to detect when the player would leave the bounds of the screen (using the same polygon to confine cinemachine), to reset the player. Which now that I think of it I could just check if the object is visible to the camera oops lol
    Will probably go through with that solution.

    Would a CompositeCollider2D connected to a tilemap still cause issues that second case? I would assume it would end up simplifying the whole shape.

    EDIT: I suppose my other question would be then, if you want to use a cinemachine confiner, how can i specify a bounding shape without making a level-wide collider? Set it to a different layer? Bad of me but I haven't touched layers much yet. Still FAIRLY new to Unity
     
    Last edited: Aug 2, 2023
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    The problem is that you can tell the physics to only allow it to interact with a specific layer but it still has to (quickly) discount everything within its view in what is known as the broadphase (spatial database) so it's unnecessarily having to discount things.

    Reducing the number of shapes it has to search improves it but it's still wasted effort.

    As I said though, if it works for you without issue then that's fine but I thought mentioning this was important too.
     
    jaeschkeshaun likes this.