Search Unity

Question How can I make my enemy AI stop shooting the player if they are behind the wall?

Discussion in 'Scripting' started by AGENT_KEL, Mar 14, 2023.

  1. AGENT_KEL

    AGENT_KEL

    Joined:
    Jan 24, 2023
    Posts:
    17
    I am pretty new to unity and now working with enemy AI for my game. I made some progress and added attack, chase and patroling states but now I am stuck with one issue where enemy tries to shoot through walls. Is there any way to fix this? Here is my enemy AI script:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.AI;
    3.  
    4. public class EnemyAi : MonoBehaviour
    5. {
    6.     public NavMeshAgent agent;
    7.  
    8.     public Transform player;
    9.  
    10.     public LayerMask whatIsGround, whatIsPlayer;
    11.  
    12.     public int maxHealth;
    13.     public int currentHealth;
    14.     Ragdoll ragdoll;
    15.     public bool isDead;
    16.  
    17.     //Patroling
    18.     public Vector3 walkPoint;
    19.     bool walkPointSet;
    20.     public float walkPointRange;
    21.  
    22.     //Attacking
    23.     public float timeBetweenAttacks;
    24.     bool alreadyAttacked;
    25.     public GameObject projectile;
    26.     public Transform projectilePos;
    27.  
    28.     //States
    29.     public float sightRange, attackRange;
    30.     public bool playerInSightRange, playerInAttackRange;
    31.  
    32.     Animator animator;
    33.  
    34.     private void Awake()
    35.     {
    36.         currentHealth = maxHealth;
    37.         player = GameObject.Find("Player").transform;
    38.         agent = GetComponent<NavMeshAgent>();
    39.         animator = GetComponent<Animator>();
    40.         ragdoll = GetComponent<Ragdoll>();
    41.     }
    42.  
    43.     private void Update()
    44.     {
    45.         //Check for sight and attack range
    46.         playerInSightRange = Physics.CheckSphere(transform.position, sightRange, whatIsPlayer);
    47.         playerInAttackRange = Physics.CheckSphere(transform.position, attackRange, whatIsPlayer);
    48.  
    49.         if (!playerInSightRange && !playerInAttackRange) Patroling();
    50.         if (playerInSightRange && !playerInAttackRange) ChasePlayer();
    51.         if (playerInAttackRange && playerInSightRange) AttackPlayer();
    52.  
    53.         animator.SetFloat("Speed", agent.velocity.magnitude);
    54.     }
    55.  
    56.     private void Patroling()
    57.     {
    58.         if (!walkPointSet) SearchWalkPoint();
    59.  
    60.         if (walkPointSet) agent.SetDestination(walkPoint);
    61.  
    62.         Vector3 distanceToWalkPoint = transform.position - walkPoint;
    63.  
    64.         //Walkpoint reached
    65.         if (distanceToWalkPoint.magnitude < 0.1f) walkPointSet = false;
    66.     }
    67.  
    68.     private void SearchWalkPoint()
    69.     {
    70.         //Calculate random point in range
    71.         float randomZ = Random.Range(-walkPointRange, walkPointRange);
    72.         float randomX = Random.Range(-walkPointRange, walkPointRange);
    73.  
    74.         walkPoint = new Vector3(transform.position.x + randomX, transform.position.y, transform.position.z + randomZ);
    75.  
    76.         if (Physics.Raycast(walkPoint, -transform.up, 2f, whatIsGround)) walkPointSet = true;
    77.     }
    78.  
    79.     private void ChasePlayer()
    80.     {
    81.         agent.SetDestination(player.position);
    82.     }
    83.  
    84.     private void AttackPlayer()
    85.     {
    86.         //Make sure enemy doesn't move
    87.         agent.SetDestination(transform.position);
    88.  
    89.         transform.LookAt(player);
    90.  
    91.         if (!alreadyAttacked)
    92.         {
    93.             //Attack code here
    94.             Rigidbody rb = Instantiate(projectile, projectilePos.position, projectilePos.rotation).GetComponent<Rigidbody>();
    95.             rb.AddForce(transform.forward * 32f, ForceMode.Impulse);
    96.             rb.AddForce(transform.up * 0f, ForceMode.Impulse);
    97.             animator.SetTrigger("Shoot");
    98.  
    99.             alreadyAttacked = true;
    100.             Invoke(nameof(ResetAttack), timeBetweenAttacks);
    101.         }
    102.     }
    103.  
    104.     private void ResetAttack()
    105.     {
    106.         alreadyAttacked = false;
    107.     }
    108.  
    109.     public void TakeDamage(int damage)
    110.     {
    111.         currentHealth -= damage;
    112.         if (currentHealth <= 0)
    113.         {
    114.             Die();
    115.         }
    116.     }
    117.  
    118.     private void Die()
    119.     {
    120.         isDead = true;
    121.  
    122.         EnemyAi enemyMovement = GetComponent<EnemyAi>();
    123.         NavMeshAgent enemyMovement2 = GetComponent<NavMeshAgent>();
    124.         if (enemyMovement != null)
    125.         {
    126.             enemyMovement.enabled = false;
    127.             enemyMovement2.enabled = false;
    128.         }
    129.  
    130.  
    131.         ragdoll.ActivateRagdoll();
    132.         Invoke("Delay", 5f);
    133.     }
    134.  
    135.     private void Delay()
    136.     {
    137.         Destroy(gameObject);
    138.     }
    139. }
     
  2. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    243
    After the player is nearby, you also need to raycast to him. And if the ray did not collide with the player, then there is a wall between you.
     
    Chubzdoomer and AGENT_KEL like this.