Search Unity

I need to make enemy detect player

Discussion in 'Scripting' started by svyathor, Jan 17, 2020.

  1. svyathor

    svyathor

    Joined:
    Aug 18, 2019
    Posts:
    32
    Hi, I'm making a 2D game. I need the enemy to be able to spot the player and shoot, I did it with Physics2d.Raycast, but if there is another layer in front of the enemy, it still detects the player and shoots, although the damage is not passed through the other layer to the player, but the render line I made still shoots and hits the obstacle. I need the enemy to be unable to see through the other layer. If the code is needed, I provide it.
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    If you already use Raycast, then you are probably doing something minor wrong. You should only check the first hit, and obviously make sure that you can hit other things than the player. Thus the raycast should hit the wall if it's in front of the player and if that's the case you couldnt shoot/detect the player. As soon as the placer moves in front of the wall, the raycast would hit the player and you would detect him. Your approach is fine, so you probably either get all objects hit by the ray and check if the player is contained (meaning it doesnt matter if it hits the wall), or you did use some collision layer that only contains the player, thus ignoring anything else anyways. Should be one of these two.
     
    svyathor likes this.
  3. Emolk

    Emolk

    Joined:
    Feb 11, 2014
    Posts:
    241
    You need to pass a layermask with the obstacle and the player in your Raycast call.

    https://docs.unity3d.com/ScriptReference/LayerMask.html
     
    svyathor likes this.
  4. svyathor

    svyathor

    Joined:
    Aug 18, 2019
    Posts:
    32
    Thanks for your answer
    I think that's the second thing you said. The obstacle and player have different layers. Now enemy is shooting trought obstacles(obstacles contains collider and layer) and deals damage i think that is due to the fact that i changedthe script a little. In the enemyshooting script:
    Code (CSharp):
    1.  
    2.     public const float Seconds = 0.02f;
    3.     public LayerMask PlayerLayer;
    4.     public Transform firePoint;
    5.     public int damage = 40;
    6.     public GameObject impactEffect;
    7.     public LineRenderer lineRenderer;
    8.     public int shootDist;
    9.  
    10.  
    11.  
    12.     void Start()
    13.     {
    14.        
    15.     }
    16.  
    17.     // Update is called once per frame
    18.     void FixedUpdate()
    19.     {
    20.  
    21.             if (Physics2D.Raycast(firePoint.position, firePoint.right,shootDist, PlayerLayer))
    22.             {
    23.                 StartCoroutine(Shoot1());
    24.                 Debug.Log("shoot");
    25.             }
    26.        
    27.  
    28.        
    29.     }
    30.  
    31.     IEnumerator Shoot1()
    32.     {
    33.  
    34.         RaycastHit2D hitInfo = Physics2D.Raycast(firePoint.position, firePoint.right, shootDist, PlayerLayer);
    35.  
    36.  
    37.         if (hitInfo)
    38.         {
    39.             HealthBar health = hitInfo.transform.GetComponent<HealthBar>();
    40.  
    41.             if (health != null)
    42.             {
    43.                 health.TakeDamage(damage);
    44.             }
    45.             Instantiate(impactEffect, hitInfo.point, Quaternion.identity);
    46.  
    47.             lineRenderer.SetPosition(0, firePoint.position);
    48.             lineRenderer.SetPosition(1, hitInfo.point);
    49.         }
    50.         else
    51.         {
    52.             lineRenderer.SetPosition(0, firePoint.position);
    53.             lineRenderer.SetPosition(1, firePoint.position + firePoint.right * 100);
    54.         }
    55.         lineRenderer.enabled = true;
    56.  
    57.        
    58.  
    59.         yield return new WaitForSeconds(Seconds);
    60.  
    61.         lineRenderer.enabled = false;
    62.  
    63.  
    64.  
    65.     }
    thank you for any response
     
  5. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Yeah, you are checking for 'PlayerLayer'. You should either remove the layer completely (unless there are objects with an collider you can detect the player through, like maybe a window) or create a new layer that contains the player and all other things the ray interacts with (player, wall, ground, but not window for example).
     
    svyathor likes this.
  6. svyathor

    svyathor

    Joined:
    Aug 18, 2019
    Posts:
    32
    Thanks,
    Ok and then check for tag?
     
  7. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    If you remove the layer completely you dont need to check for a tag or anything. Just take a look at the example:
    https://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html
    You can call the method with different sets of parameters, it's not required to add all of them. Thus you can just remove the layer and it will collide with everything that has a collider.
     
    svyathor likes this.
  8. svyathor

    svyathor

    Joined:
    Aug 18, 2019
    Posts:
    32
    Thanks for answer. I don't remove layer completely. I make layer for objects that I can hit with raycast.