Search Unity

Feature Request Rigidbody2D - Filter interactions by Z coordinate

Discussion in '2D Experimental Preview' started by ZimM, Apr 15, 2017.

  1. ZimM

    ZimM

    Joined:
    Dec 24, 2012
    Posts:
    955
    An awesome recent addition to Unity is that some overloads of Physics2D methods now have minDepth/maxDepth arguments that allow to only include objects within a range of Z coordinate values. However, a corresponding option is strangely missing from Rigidbody2D itself.

    What I was trying to achieve is something similar to Rayman Legends, in particularly - how in that game physical objects can be placed on different planes with different Z coordinates without interfering. For example, at 3:20 mark here:

    You can clearly see that there are two level planes that do not interact with each other, even though Rayman Legends is a strictly 2D game.

    Another example is any classic 2D beat ’em up game, like Double Dragon or Streets of Rage. While these games are pretty much 2D, they still use the Z coordinate - the player can only interact with objects that are on approximately the same depth as himself.

    Unfortunately, this doesn't seems possible in Unity, unless I am going to abandon all the neat 2D physics stuff and do everything manually via raycasts. The other option is to use 3D physics with all objects having zero thickness colliders, but that sounds incredibly overkill. Not only because of increased resource consumption, but also because, again, I won't be able to use all the neat 2D physics stuff like Effectors.

    It would be absolutely amazing if a MinDepth/MaxDepth properties would be added to the Rigidbody2D itself, in one form or another.
     
    Last edited: Apr 15, 2017
  2. AssembledVS

    AssembledVS

    Joined:
    Feb 23, 2014
    Posts:
    248
    Perhaps I'm reading your post incorrectly, but isn't the solution as simple as switching the other plane's collision layer to prevent physics interactions and switching the visual sorting layer to always be in front of/behind the plane? This is what I do when I want to have an object share a coordinate point with another object but for both of the objects to act like they are on different levels (for example, a character that's under a bridge while another character is directly on top of it, on the bridge).
     
  3. ZimM

    ZimM

    Joined:
    Dec 24, 2012
    Posts:
    955
    That might be a solution, but only in simple cases. Again, picture a classic beat-em-up game. The "layers" of interaction are not fixed. Instead, for example, the player can only attack an enemy if the difference between the Z coordinate of player and enemy is not larger that some value. And they are not aligned or a grid or something, so it is not possible to assign a specific layer.

    And if I go back to Rayman Legends example... That still won't really work, since there might be quite a few "planes" in the level, let's say 5, for example. Now, I also use layers for defining physics interaction, so I have layers like Ground, Passthrough, and Platform... How is that going to work in this setup? Maybe I can list all the possible combinations of "planes" and corresponding layers, and get a ridiculous list of layers like this:
    This alone would eat up 15 layers. And let me remind you, Unity only allows for 32 layers total, from which only 24 are user-defined. And what if I need more layers (for example, I might want to have some physics stuff going on in background for pure decoration)? This quickly goes out of hand. None of these problems would exist if it was possible to define a Z coordinate filter directly on Rigidbody2D, so physical objects on different planes would not interact with each other.
     
    Last edited: Apr 15, 2017
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    3,679
    There's going to be an update to the 2D physics road-map after the Easter break that'll contain many items. One of which is Depth-based (Transform Z position) collision detection. It'll be in the research section of the road-map.

    This is actually relatively simple to implement however how the user specifies the depths is undefined. One method is to be able to specify named depth-ranges. Only Collider2D with Transform Z within the same range can contact. Alternately there's the idea you raised about a fixed separation delta so anything within this delta can contact which is by far the easiest to set-up and only requires a single value for the delta to be configured.

    When deciding if two colliders should contact, the algorithm needs to be super fast which the existing layer-based set-up is. The Transform Z would be slightly slower as that is not stored inside the 2D physics system so the Transform components of both Collider2D would need to be acquired and the Z extracted. Nothing too bad but it's something to consider.
     
  5. ZimM

    ZimM

    Joined:
    Dec 24, 2012
    Posts:
    955
    It is great to hear that this is going to be researched. It would simplify things a lot in the project I'm working on. The workaround I am using currently is to call Physics2D.IgnoreCollision on each pair of objects that are on different depth planes. As you might have guessed, the performance is absolutely horrendous :)

    I believe both approaches are valid in different situations. The separation delta approach would suit the beat-em-up example, and named depth ranges approach might be somewhat better for the Rayman Legends example.

    Having said that... any chance this feature will be available for testing in 2D Preview 4 or 5?
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    3,679
    No. It's more likely as a completely separate custom build as/when it's being looked at.
     
  7. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    861
    FWIW, you can actually get that to work with acceptable performance within certain parameters, if you can't wait until the actual feature is done. Do an OverlapCircle every frame and ignore colliders that are outside your depth threshold. When those colliders enter your threshold, you unignore and collisions work as expected. This would not scale well, but for relatively few objects it's alright, it's something we have used before in production.
     
  8. ZimM

    ZimM

    Joined:
    Dec 24, 2012
    Posts:
    955
    That's the problem. I have 1000's of objects...
     
  9. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    861
    Yeah, in our case, it's relatively few objects changing depth and it works alright for that, as only those need to use it.
     
unityunity