Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  4. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

ContactFilter2D for raycasting is unintuitive

Discussion in 'Physics' started by heskey30, Jun 5, 2017.

  1. heskey30

    heskey30

    Joined:
    May 3, 2014
    Posts:
    3
    Today I had a very frustrating experience with one of Unity's new features. It shouldn't have been this hard to make a raycast (2D) work. And I'll be the first to admit, it was my fault. But in my defense I've been spoiled by Unity's (usually) excellent UX.

    This is a series of events that cost me over an hour of thorough debugging because of some some design decisions that.... well, I don't understand.

    The new Physics2D raycast seems to have no option for both a layermask and a raycasthit output.

    Well, I guess I need to use the new ContactFilter2D
    . I add the layers to the filter.layerMask field and put it into the raycast.

    My ray collides with all layers, which is not what I wanted.

    I spend a while making sure that all my layers are fine. Layers are a bit difficult, so I assume I did them wrong. The true bug didn't occur to me because it just doesn't make sense.

    The filter.useLayerMask needs to be separately set to true even if the filter.layerMask contains something. (huh?) I fixed it.

    Now my ray does not collide with triggers. Well, you can probably guess the problem, but again I didn't realize and messed with physics settings while frantically googling for a bit.

    It turns out if you use a ContactFilter2D it overrides your physics settings on raycasting and just ignores triggers unless you manually set it to hit triggers. ​

    Well, this is not one of my shining moments of coding prowess. But it is not one of Unity's shining moments either. Hidden defaults and unintended side effects are what I expect from my fellow game developers, not the tools I use.

    It seems like useLayerMask does not need to be a public field. It should be set automatically when adding to the layerMask. It seems like useTriggers should default to the physics settings, not override them silently whenever you use ContactFilter2D.
     
    Deeeds likes this.
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,401
    So you don't read documentation then? https://docs.unity3d.com/ScriptReference/ContactFilter2D.html

    It sounds like you spent a lot of time guessing when you could've easily seen: https://docs.unity3d.com/ScriptReference/ContactFilter2D.SetLayerMask.html

    > Sets the layerMask filter property using the layerMask parameter provided and also enables layer mask filtering by setting useLayerMask to true.

    So we spent time allowing you to turn options on/off without being forced to modify the arguments to those whilst also adding convenience functions that not only set the args but automatically turn on those functions to save you having to separately turn them on. Also added documentation that clearly states that.

    I believe it seems you should perhaps read the documentation.
     
    dotsquid and hippocoder like this.
  3. heskey30

    heskey30

    Joined:
    May 3, 2014
    Posts:
    3
    I'm not here for an apology or for Unity developers to admit they're wrong. I know I'm wrong and it is a little embarrassing to post this here. But I think this could be improved.

    Anyone can make code that is usable by reading the documentation.
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,401
    I'm trying to understand how it can be improved as it does what you suggested it should do i.e. automatically set the "useLayerMask" to true when you set it.
     
    Last edited: Jun 6, 2017
  5. heskey30

    heskey30

    Joined:
    May 3, 2014
    Posts:
    3
    It seems like it doesn't need both useLayerMask and a public layerMask variable. Maybe just have the layerMask variable accessors also turn on the boolean? Or maybe you could have this set up in the constructor, which is the first thing anyone looks at. Maybe both.
     
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,401
    So how do you turn the filtering off then for each option? It does need to use "useLayerMask" otherwise there's no way to turn the filtering off for it and the same goes for the other filter options.

    Original feedback was not to do this as it's just too many implicit actions. Instead we added methods which set them and turn the option on and were documented as doing so. This is convenient for not only turning the filter on but also setting a range in a single method.

    Structs cannot have an explicit parameterless constructor in C# which is why we added "ContactFilter2D.NoFilter()" for convenience which we also used internally (when you call physics queries that don't take a ContactFilter2D we use this to produce no filtering as all internal code go throughs the same code path).
     
    Last edited: Jun 6, 2017
  7. robbel

    robbel

    Joined:
    Nov 11, 2016
    Posts:
    5
    You're being passive aggressive. OP was very reasonable. He even said it wasnt his shiniest moment. Your community members will vary in skill (which, as a programmer, includes reading the documentation). When googling stuff that led me here i was trying to figure out what the RaycastHit2D[] parameter is used for when raycasting using ContactFilter2D. I wasnt able to find it in the documentation. So while i greatly(!) appreciate the work you do, maybe there is further room for improvement in either documentation intuitivity or training resource. and if im being stupid, dont - as a company representative - get angry at me for that.
     
    Last edited: Jan 30, 2018
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,401
    There's no anger here and I took the time to explain each point carefully so I'm not sure why you're inferring I'll get angry at you. Note that last post was 7 months ago so this is an old thread.

    You are correct and that's always true.
     
  9. GoalLine

    GoalLine

    Joined:
    Mar 23, 2017
    Posts:
    6
    I know how to use Physics.Raycast (3D) just fine, but I am also having a hard time trying to figure out this implementation to Physics2D.Raycast using ContactFilter.
    Code (CSharp):
    1.  
    2. ContactFilter2D filter;
    3. filter.NoFilter();
    4. RaycastHit2D[] hits;
    5. if(Physics2D.Raycast(m_GroundCheck.position, m_GroundCheck.right, filter, hits)){}
    MelvMay, you seem pretty confident that others are not reading the documentation. I feel the documentation is misleading. With this code above, I get an error because Physics2D.Raycast is returning an int and not a bool. I really want to figure this out rather than avoiding it. I just want to get a list of what objects were hit. :/

    Code (CSharp):
    1. RaycastHit2D hits = Physics2D.Raycast(m_GroundCheck.position, -m_GroundCheck.right, 2f);
    2. if(hits.collider != null && hits.collider.tag == "Ground"){
    3.     Debug.Log("Hit ground left");
    4. }
    This code works obviously, but I im still stuck on the ContactFilter method.
     
    Last edited: Aug 30, 2018
    Deeeds likes this.
  10. laszlar

    laszlar

    Joined:
    Jul 9, 2014
    Posts:
    1
    I very much agree with you, and I'm having a similar problem. Sometimes the documentation gives a brief example on how it's used, and case uses. In this case, there is very little information on how to use it. Thank you [MelvMay] for pointing us to a variable to pass in the documentation, but that's all there is. Maybe the documentation should be updated.
     
  11. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    646
    The age of this thread is irrelevant to its significance.