VizKa

Shooting game AI

May 6th, 2023
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.33 KB | Gaming | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Transactions;
  5. using UnityEngine;
  6. using UnityEngine.AI;
  7. using Random = UnityEngine.Random;
  8.  
  9. public class AI : MonoBehaviour
  10. {
  11.     //General variables
  12.     private GameObject player;
  13.     private SpawnManager spawnManager;
  14.  
  15.     //Movement variables
  16.     private NavMeshAgent myAgent;
  17.     [SerializeField] private float speedRangeTop = 15;
  18.     [SerializeField] private float speedRangeBottom = 6;
  19.     private Transform goal;
  20.     private Rigidbody myRigidbody;
  21.     public bool isMoving;
  22.    
  23.     //Player in range variables
  24.     private RaycastHit raycastHit;
  25.     private bool playerInRange;
  26.     private LayerMask whatIsPlayer;
  27.     [SerializeField] private float sphereRangeRadius = 20;
  28.    
  29.     //Health system variables
  30.     [SerializeField] public int health = 100;
  31.     [SerializeField] private float pushback = 2;
  32.     [SerializeField] private float recoilCooldown = 1;
  33.  
  34.     //Attack variables
  35.     [SerializeField] private int damage = 20;
  36.     [SerializeField] public float attackCooldown = 3;
  37.     private bool attacked;
  38.     public bool isAttacking;
  39.     private float sphereHitRadius = 2;
  40.     public bool hitted;
  41.     private EnemyDamage myEnemyDamage;
  42.     private float attackDelay = 0.5f;
  43.    
  44.     //Color variables
  45.     private Gradient gradient;
  46.     [SerializeField] private GameObject body;
  47.     [SerializeField] private GameObject leftBackLeg;
  48.     [SerializeField] private GameObject leftFrontLeg;
  49.     [SerializeField] private GameObject rightBackLeg;
  50.     [SerializeField] private GameObject rightFrontLeg;
  51.  
  52.    
  53.     // Start is called before the first frame update
  54.     void Start()
  55.     {
  56.         whatIsPlayer = LayerMask.GetMask("Player");
  57.         myAgent = this.GetComponent<NavMeshAgent>();
  58.         player = GameObject.Find("player");
  59.         spawnManager = GameObject.Find("SpawnManager").GetComponent<SpawnManager>();
  60.         myAgent.speed = Random.Range(speedRangeBottom, speedRangeTop);
  61.         myEnemyDamage = this.GetComponent<EnemyDamage>();
  62.        
  63.         //Create color keys for gradient
  64.         gradient = new Gradient();
  65.         CreateGradient();
  66.         ChangeColor();
  67.  
  68.     }
  69.  
  70.     // Update is called once per frame
  71.     void Update()
  72.     {
  73.         if (health < 0)
  74.         {
  75.             DestroyYourself();
  76.         }
  77.        
  78.         CheckIfPlayerInRange();
  79.        
  80.         if (playerInRange && !attacked)
  81.         {
  82.             Attack();
  83.             isAttacking = true;
  84.             StartCoroutine(AttackCoolDown());
  85.         }
  86.  
  87.         speedRangeTop += (spawnManager.wave * 0.2f);
  88.         speedRangeBottom += (spawnManager.wave * 0.1f);
  89.  
  90.     }
  91.  
  92.     private void FixedUpdate()
  93.     {
  94.         if (attacked)
  95.         {
  96.             AIMovementAfterAttack();
  97.         }
  98.         else
  99.         {
  100.             AIMovement();
  101.         }
  102.        
  103.     }
  104.  
  105.     private void AIMovement()
  106.     {
  107.         if (myAgent.enabled)
  108.         {
  109.             isMoving = true;
  110.             myAgent.SetDestination(player.transform.position);
  111.             this.transform.LookAt(player.transform.position);
  112.         }
  113.         else
  114.         {
  115.             isMoving = false;
  116.         }
  117.        
  118.        
  119.     }
  120.  
  121.     private void AIMovementAfterAttack()
  122.     {
  123.         if (myAgent.enabled)
  124.         {
  125.             isMoving = true;
  126.             myAgent.SetDestination(player.transform.position - this.transform.position + (player.transform.position*0.005f));
  127.             this.transform.LookAt(player.transform.position);
  128.         }
  129.         else
  130.         {
  131.             isMoving = false;
  132.         }
  133.     }
  134.  
  135.     private void CheckIfPlayerInRange()
  136.     {
  137.         playerInRange = Physics.CheckSphere(transform.position, sphereRangeRadius, whatIsPlayer);
  138.     }
  139.  
  140.     //Debug the SphereCast used to check if the player is in range
  141.     private void OnDrawGizmosSelected()
  142.     {
  143.         Gizmos.color = Color.red;
  144.         Gizmos.DrawWireSphere(transform.position, sphereRangeRadius);
  145.        
  146.         Gizmos.color = Color.green;
  147.         Gizmos.DrawWireSphere(transform.position + transform.forward*2, sphereHitRadius);
  148.     }
  149.  
  150.     private void Attack()
  151.     {
  152.         StartCoroutine(AttackDelay());
  153.  
  154.     }
  155.     private void DestroyYourself()
  156.     {
  157.         spawnManager.EnemyDied();
  158.         player.GetComponent<playerController>().RestoreDrain();
  159.         Destroy(gameObject);
  160.     }
  161.  
  162.     private IEnumerator AttackCoolDown()
  163.     {
  164.         attacked = true;
  165.         yield return new WaitForSeconds(0.9f);
  166.         isAttacking = false;
  167.         yield return new WaitForSeconds(attackCooldown-0.9f);
  168.         attacked = false;
  169.     }
  170.    
  171.     private IEnumerator PushbackCoolDown()
  172.     {
  173.         yield return new WaitForSeconds(recoilCooldown);
  174.         myAgent.enabled = true;
  175.     }
  176.  
  177.     private IEnumerator AttackDelay()
  178.     {
  179.         yield return new WaitForSeconds(attackDelay);
  180.         myAgent.enabled = false;
  181.         if (Physics.CheckSphere(transform.position + transform.forward * 2, sphereHitRadius, whatIsPlayer) && !hitted)
  182.         {
  183.             player.GetComponent<playerController>().TakeDamage(damage);
  184.         }
  185.         yield return new WaitForSeconds(0.15f);
  186.         myAgent.enabled = true;
  187.     }
  188.  
  189.     public void ReduceHealth(int bulletDamage)
  190.     {
  191.         this.health -= bulletDamage;
  192.         ChangeColor();
  193.         myEnemyDamage.SpawnDamageText(bulletDamage);
  194.     }
  195.    
  196.     private void OnTriggerEnter(Collider collision)
  197.     {
  198.         //Disable Agent so Rigidbody can be used to apply the recoil and then reactivate it
  199.         myAgent.enabled = false;
  200.         Vector3 vectorPushback = this.transform.position + ((-this.transform.forward) * pushback);
  201.         Vector3.Lerp(this.transform.position, vectorPushback, recoilCooldown);
  202.         StartCoroutine(PushbackCoolDown());
  203.     }
  204.  
  205.     //Change AI color based on its health
  206.     private void ChangeColor()
  207.     {
  208.         body.gameObject.GetComponent<Renderer>().material.SetColor("_BaseColor", gradient.Evaluate(health/100f));
  209.         leftBackLeg.gameObject.GetComponent<Renderer>().material.SetColor("_BaseColor", gradient.Evaluate(health/100f));
  210.         leftFrontLeg.gameObject.GetComponent<Renderer>().material.SetColor("_BaseColor", gradient.Evaluate(health/100f));
  211.         rightBackLeg.gameObject.GetComponent<Renderer>().material.SetColor("_BaseColor", gradient.Evaluate(health/100f));
  212.         rightFrontLeg.gameObject.GetComponent<Renderer>().material.SetColor("_BaseColor", gradient.Evaluate(health/100f));
  213.     }
  214.  
  215.     private void CreateGradient()
  216.     {
  217.         //Set the gradient mode
  218.         gradient.mode = GradientMode.Blend;
  219.  
  220.         //Create the arrays for the gradient
  221.         GradientColorKey[] myGradientColorKeys = new GradientColorKey[2];
  222.         GradientAlphaKey[] alphaKeys = new GradientAlphaKey[2];
  223.        
  224.         //Set the colors to blend and where to blend
  225.         myGradientColorKeys[0].color = Color.grey;
  226.         myGradientColorKeys[1].color = Color.cyan;
  227.         myGradientColorKeys[0].time = 0f;
  228.         myGradientColorKeys[1].time = 1f;
  229.  
  230.         //Set the alpha to blend
  231.         alphaKeys[0].alpha = 1.0f;
  232.         alphaKeys[0].time = 0.0f;
  233.         alphaKeys[1].alpha = 1.0f;
  234.         alphaKeys[1].time = 1.0f;
  235.  
  236.         //Set the keys and alpha arrays to be the ones for the gradient
  237.         gradient.SetKeys(myGradientColorKeys, alphaKeys);
  238.     }
  239. }
  240.  
Advertisement
Add Comment
Please, Sign In to add comment