Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Physics.OverlapSphere layer

Discussion in 'Scripting' started by BrettFromLA, Jun 19, 2010.

  1. BrettFromLA

    BrettFromLA

    Joined:
    Jan 29, 2009
    Posts:
    244
    I'm looking forward to figuring this out 5 seconds after I post this. But in the meantime....

    Physics.OverlapSphere works as I expect until I include a layerMask parameter. Once I include that, it doesn't find any colliders near it. Here's the code I'm using:

    Code (csharp):
    1.  
    2. function doGrab () {
    3.     var a_colliders;
    4.     var i_grab_layer : int = LayerMask.NameToLayer("ToGrab");
    5.  
    6.     // Grab at least 5 colliders, if they're less than 30 units away
    7.     while ((Physics.OverlapSphere(transform.position, i_diameter, i_grab_layer).length < 6)  (i_diameter < 30)) {
    8.         i_diameter ++;
    9.     }
    10.     a_colliders = Physics.OverlapSphere(transform.position, i_diameter, i_grab_layer);
    11. }
    12.  
    All the things to grab are on the "ToGrab" layer. And they're closer than 30 units away. But the i_diameter variable in the loop grows to 30, the loop bails out, and a_colliders winds up with a length of 0.
     
  2. BrettFromLA

    BrettFromLA

    Joined:
    Jan 29, 2009
    Posts:
    244
    Just like I promised, I figured it out! (Note the time stamp on my last post and on this one. And figure it took me a few minutes to write this!)

    I just included a public (inspector) variable for the layer, and it started working.

    Code (csharp):
    1.  
    2. public var lm_grab_layer : LayerMask;
    3.  
    4. function doGrab () {
    5.     var a_colliders;
    6.     var i_grab_layer : int = LayerMask.NameToLayer("ToGrab");
    7.  
    8.     // Grab at least 5 colliders, if they're less than 30 units away
    9.     while ((Physics.OverlapSphere(transform.position, i_diameter, lm_grab_layer).length < 6)  (i_diameter < 30)) {
    10.         i_diameter ++;
    11.     }
    12.     a_colliders = Physics.OverlapSphere(transform.position, i_diameter, lm_grab_layer);
    13. }
    14.  
     
  3. Gunslinger3

    Gunslinger3

    Joined:
    Aug 21, 2012
    Posts:
    1
    Do it like this:
    var colliders : Collider[] = Physics.OverlapSphere(cube.transform.position, 100, 1 << 8);

    Where 8 is the layer you try to find. What happens is that the 1 gets shifted 8 steps to the left, so:
    00000000001 becomes 0100000000.

    The alert reader might see that it's the 9:th bit beeing set. Yeah, it is. This is because the layers are 0-based. The first layer is the first but and it has the number 0. The ninth layer is the ninth bit and it has the number 8. Same as indexes in arrays.

    To find several layers you want a bitmask with a bitwise OR operator: | (single pipe character):
    1 << 8 | 1 << 4 | 1 << 2
    This will combine the three bitmasks:
    0100000000
    0000010000
    0000000100
    Into:
    0100010100
    And this will match layer 8, 4 and 2.
     
    CaptainNoah, FonzoUA and juanje_89 like this.
  4. randrews33

    randrews33

    Joined:
    Nov 4, 2013
    Posts:
    2
    I had the same issue as the poster, and solved it in the same way. Can anyone explain why simply using a call to LayerMask.NameToLayer(layerName) causes the objects to be ignored, while using a public variable works? This is the only instance I've run into problems with making calls like this - never seems to be an issue for me when comparing layers during collision handling. I understand how the bit masking works, like Gunslinger3 described, but I don't understand why the layer masks operate differently in those two scenarios
     
    CaptainNoah likes this.
  5. CiberX15

    CiberX15

    Joined:
    Jul 31, 2013
    Posts:
    15
    Yeah so I had that exact problem too. What appears to be happening is LayeraMask.NameToLayer("some layer name") seems to return the _index_ of the layer, but not its bitshifted ID that some of the physics checks use. If you use the following it works:

    1<<LayeraMask.NameToLayer("some layer name")


    P.S. yes I am aware this is a 4 year necro but I post in the hope that it helps some future dev like myself when they come across it ;)
     
  6. TadasTalalas

    TadasTalalas

    Joined:
    Nov 7, 2016
    Posts:
    33
    And it certainly did!! :)))
     
    natubeast likes this.