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

Set layer to ignore in linecast via code, then back, not working?

Discussion in 'Scripting' started by XJonOneX, Jan 22, 2018.

  1. XJonOneX

    XJonOneX

    Joined:
    Dec 19, 2017
    Posts:
    110
    Hi all,

    So I *think* I know what I'm doing. I had this working perfectly for a camera to detect walls and objects, but to ignore the player object. All I had to do was keep the player object on the 'Ignore Linecast' layer that I made.

    Well, like always, I don't want to reserve something so handy for just one purpose. So I figured, change the layer of the player to the one to use for ignoring linecasts, before the actual linecast, then swap it back to whatever it may have been before the linecast.

    Code (CSharp):
    1. int oldLayer = targetObject.layer;
    2. targetObject.layer = LayerMask.NameToLayer("Ignore Linecast");
    3. layerMask = 1 << LayerMask.NameToLayer("Ignore Linecast");
    4. layerMask = ~layerMask;
    5. if (Physics.Linecast(target, target + (newDirection * distance), out hit, layerMask))
    6. {
    7.       newDistance = hit.distance;
    8.       lineHit = true;
    9. }
    10. else
    11. { lineHit = false; }
    12.  
    13. targetObject.layer = oldLayer;
    I steped through this code in VS2017, and the layers are indeed changing appropriately line to line. (from 0, to 8, back to 0) However, the linecast hits my player object which should be (and apparently is?) on the 'Ignore Linecast' layer. While running the project, if I set the layer of my player to 'Ignore Linecast' everything works as it should. (Of course, then, the layer is always set to 'Ignore Linecast' back and forth)

    Does the frame need to update or something like that before the layer update will be caught by a linecast? Is this a bug? Am I not doing this right? :confused:
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Edit: This post was wrong.

    Try changing this line:
    Code (csharp):
    1. layerMask = 1 << LayerMask.NameToLayer("Ignore Linecast");
    to simply this:
    Code (csharp):
    1. layerMask = LayerMask.NameToLayer("Ignore Linecast");
    2. // or (just on 1 line)..
    3. layerMask = ~(LayerMask.NameToLayer("Ignore Linecast"));
     
    Last edited: Jan 22, 2018
  3. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    I've never tried this, but it really might need to wait until the next FixedUpdate (rather than the next frame) for the physics engine to register the change. Seems like the kind of quirk Unity would have. Not really a huge deal though, an arguably better way of doing this is to create a 2-element array and use RaycastNonAlloc (far better performance) with that array and just skip the player object if it's hit. This'll likely be as fast or faster than your current method, but without any layer changes being necessary.

    Unless there's some reason you need for this to be a linecast instead of a raycast? I've never actually seen a legitimate use for a linecast, to be perfectly honest.
     
  4. XJonOneX

    XJonOneX

    Joined:
    Dec 19, 2017
    Posts:
    110
    It just now donned on me as I was fiddling with it some more. Unity asked my to set the layer on all my children. That was my problem, I was setting the layer on the parent, but not the children. :oops:
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Glad you fixed it a different way.
     
    Last edited: Jan 22, 2018
  6. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    While I'm still fairly certain that momentary changes in layers are going to cause you incredibly difficult-to-diagnose problems down the road ^_~
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    heh, could be :) Never done it, myself.
     
  8. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Nope, I was wrong. lol. This is the second time I've corrected myself on this issue, I think. sigh.
     
  9. XJonOneX

    XJonOneX

    Joined:
    Dec 19, 2017
    Posts:
    110
    The mask code is what I found in the Unity manual and it's been working, but I'll try your suggestion methos5k. :)

    This is all rough as rocks coding though, a lot of it is puzzle pieces I've trimmed and used a hammer to fit together. ;) I'm still wading through the prototyping phase, seeing what I can get away with in Unity and what I can't. (Which at this rate I've been able to do every single thing I want)

    I'm totally going to look at RaycastNonAlloc() for the camera raycast. Again, linecast was used because that's what was used in example code. Uber Unity Noob here when it comes to under the hood stuff. :) At this point, I only want to switch layers momentarily while some odd bit of code runs, so as long Unity executes it like: layer change -> special code requiring layers -> back to original layer, I should be fine. :D

    Thanks for your help guys!
     
  10. XJonOneX

    XJonOneX

    Joined:
    Dec 19, 2017
    Posts:
    110
    It's ok, we've all been there. I can't count my own personal times. I blame lack of caffeine. :D
     
  11. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Everytime I get something wrong, I'm that much closer to remembering to get it right. That's what I tell myself :) lol