Search Unity

Question Linecast and LayerMask

Discussion in 'Scripting' started by Only4gamers, Sep 25, 2021.

  1. Only4gamers

    Only4gamers

    Joined:
    Nov 8, 2019
    Posts:
    327
    Hello everyone,
    I am trying to use Linecast2D in my game but I didn't able to get the result I want.
    New.jpg

    In my 2D strategy game Point Defense Turrets can intercept incoming enemy missiles, as you can see in the image above. When Linecast successfully hit the target missile, Turret should rotate toward the target missile. But it's not happening. Because currently Force Field is blocking the Linecast.

    This is my script attached on Point Defence Turret
    Code (CSharp):
    1.  
    2. void Start()
    3.     {
    4.         if(transform.parent.localPosition.y > 0)
    5.         {
    6.             defaultRotation = Quaternion.Euler(0, 0 , 90);
    7.         }
    8.         else if(transform.parent.localPosition.y < 0)
    9.         {
    10.             defaultRotation = Quaternion.Euler(0, 0 , -90);
    11.         }
    12.  
    13.         transform.localRotation = defaultRotation;
    14.     }
    15. private int layerMask = 8;
    16.  
    17.     void FixedUpdate()
    18.     {
    19.         // Closest Missile is closestTarget
    20.         if(closestTarget != null)
    21.         {
    22.             RaycastHit2D hit = Physics2D.Linecast(firePoint.position, closestTarget.position, layerMask);
    23.             if(hit)
    24.             {
    25.                 Debug.Log(hit.transform.name);
    26.                 // Something is blocking Linecast so rotate Turret to default State.
    27.                 transform.localRotation = Quaternion.Slerp(transform.localRotation, defaultRotation, Time.deltaTime * rotateSpeed);
    28.             }
    29.             else
    30.             {
    31.                 // Linecast successfully hitting the target missile, so rotate toward the missile
    32.                 distanceFromMissile = Vector3.Distance (transform.position, closestTarget.position);
    33.                 if(distanceFromMissile < 40)
    34.                 {
    35.                     Vector3 vectorToTarget = closestTarget.position - transform.position;
    36.                     float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
    37.                     Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
    38.                     transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * rotateSpeed);
    39.                 }
    40.             }
    41.         }
    42.     }
    Let me know if you have any doubts.
    Please help me, I am having trouble understanding Linecast and LayerMask from months.
     
    Last edited: Sep 25, 2021
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    Bunny83 and Only4gamers like this.
  3. Only4gamers

    Only4gamers

    Joined:
    Nov 8, 2019
    Posts:
    327
    Yes, I know this. Thanks for the reply.
    What I am trying in above script is:
    Linecast casting from the Point defense turret which is attached in the Player ships should only be blocked by the same Player ship only. How to achieve this? Player ship and its children Layer is Layer Number 3.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    I think we can be pretty confident the Unity linecast API works as advertised, so it's time to find out how you're mis-using it.

    First isolate the linecast in its own tiny scene and script and prove it is working properly with your layers.

    Steps to success:

    - hard wire some positions
    - do the cast
    - check what comes back

    Don't do anything else until you prove you are using linecast and layermasks properly.

    Once you prove that, then go back to your current logic and do the same thing all over, find where the issue is.

    If the problem still persists, at least we know it's not linecast.

    You must find a way to get the information you need in order to reason about what the problem is.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is

    To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494
     
    Only4gamers likes this.