Advertisement
noradninja

Enemy Controller

Oct 4th, 2023
764
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.55 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.AI;
  5.  
  6. public class EnemyController : MonoBehaviour {
  7.     public enum EnemyState {
  8.         idle,
  9.         alert,
  10.         looking,
  11.         roaming,
  12.         chase,
  13.         attack,
  14.         dodge
  15.     }
  16.     public enum enemyType {
  17.         standIn,
  18.         enemy2,
  19.         enemy3
  20.     }
  21.  
  22. //private vars
  23.     private Vector3 startingPosition;
  24.     private Collider[] rangeChecks;
  25.     private bool onMesh = false;
  26.  
  27. //public vars
  28.     [Header("Enemy Setup")]
  29.     public enemyType typeOfEnemy;
  30.     public Animator enemyAnimator;
  31.     public GameObject player;
  32.     public GameObject targetPoint;
  33.     public  GameObject randomPointObject;
  34.     public NavMeshAgent meshAgent;
  35.     public float turnSpeed = 1.0f;
  36.  
  37.    
  38.     [Header("FOV and Visibility")]
  39.     public float viewRadius;
  40.     [Range (0, 360)]
  41.     public float fovAngle;
  42.     public LayerMask targetMask;
  43.     public LayerMask obstructionMask;
  44.     public float distanceToPlayer;
  45.     public bool isPlayerNear = false;
  46.     public bool canSeePlayer = false;
  47.     [Header("Behavior")]
  48.     public EnemyState behaviorState;
  49.     public float alertDelay = 1.5f;
  50.     public float lookDelay = 1.5f;
  51.     public bool alerted = false;
  52.     public bool lookingForPlayer = false;
  53.     public bool roaming = false;
  54.     public bool isPlayerRunning;
  55.     public bool FlashlightDisabled;
  56.     public Vector3 randomCircle;
  57.     private static readonly int IsAttacking = Animator.StringToHash("isAttacking");
  58.  
  59.  
  60.     // Use this for initialization
  61.     private void Start () {
  62.         startingPosition = transform.position;
  63.         enemyAnimator = GetComponent<Animator>();
  64.         RandomizePoint();
  65.     }
  66.        
  67.     // Update is called once per frame
  68.     private void Update () {
  69.         distanceToPlayer = Vector3.Distance(player.transform.position, this.transform.position);
  70.         FlashlightController.FlashlightDisabled = FlashlightController.FlashlightOff;
  71.         isPlayerRunning = PlayerController.isRunning;
  72.        
  73.         if (distanceToPlayer < viewRadius){
  74.             isPlayerNear = true;
  75.             behaviorState = EnemyState.alert;
  76.         }
  77.  
  78.         if (distanceToPlayer <= 1.5f){
  79.             behaviorState = EnemyState.attack;
  80.         }
  81.        
  82.    
  83.         if (distanceToPlayer > viewRadius){
  84.             isPlayerNear = false;
  85.             alerted = false;
  86.             canSeePlayer = false;
  87.         }
  88.  
  89.         if (isPlayerNear){
  90.  
  91.             Vector3 dir = player.transform.position - transform.position;
  92.             Quaternion lookRotation = Quaternion.LookRotation(dir);
  93.             Vector3 rotation = Quaternion.Lerp(transform.rotation, lookRotation, Time.deltaTime * turnSpeed).eulerAngles;
  94.             transform.rotation = Quaternion.Euler(0f, rotation.y, 0f);
  95.         }
  96.  
  97.  
  98.         switch (typeOfEnemy){
  99.             case enemyType.standIn:
  100.                 StandInStates();
  101.                 break;
  102.  
  103.             case enemyType.enemy2:
  104.                 Type2States();
  105.                 break;
  106.  
  107.             case enemyType.enemy3:
  108.                 Type3States();
  109.                 break;
  110.  
  111.         }
  112.        
  113.     }
  114.  
  115.     private void Type3States()
  116.     {
  117.         switch (behaviorState)
  118.         {
  119.             case EnemyState.idle:
  120.                 //play idle animation
  121.                 break;
  122.  
  123.             case EnemyState.alert:
  124.                 FaceTarget(player);
  125.                 break;
  126.            
  127.             case EnemyState.looking:
  128.  
  129.             break;
  130.  
  131.             case EnemyState.chase:
  132.                 //chase player
  133.                 break;
  134.  
  135.             case EnemyState.attack:
  136.                 //attack player
  137.                 break;
  138.  
  139.             case EnemyState.dodge:
  140.                 //dodge player attack
  141.                 break;
  142.         }
  143.     }
  144.  
  145.     private void Type2States()
  146.     {
  147.         switch (behaviorState)
  148.         {
  149.             case EnemyState.idle:
  150.                 //play idle animation
  151.                 break;
  152.  
  153.             case EnemyState.alert:
  154.                 FaceTarget(player);
  155.                 break;
  156.  
  157.             case EnemyState.looking:
  158.  
  159.             break;
  160.  
  161.             case EnemyState.chase:
  162.                 //chase player
  163.                 break;
  164.  
  165.             case EnemyState.attack:
  166.                 //attack player
  167.                 break;
  168.  
  169.             case EnemyState.dodge:
  170.                 //dodge player attack
  171.                 break;
  172.         }
  173.     }
  174.  
  175.     private void StandInStates()
  176.     {
  177.         switch (behaviorState)
  178.         {
  179.             case EnemyState.idle:
  180.                 if (!canSeePlayer){
  181.                     if (!lookingForPlayer){
  182.                         behaviorState = EnemyState.looking;
  183.                     }
  184.                 }
  185.                 if (canSeePlayer){
  186.                     behaviorState = EnemyState.alert;
  187.                 }
  188.                 if (PlayerController.currentTarget == targetPoint)
  189.                 {
  190.                     PlayerController.currentTarget = null;
  191.                 }
  192.                 // player.GetComponent<PlayerController>().lightMovement = true;
  193.                 isPlayerNear = false;
  194.                 if (enemyAnimator.GetBool(IsAttacking) == true){
  195.                     enemyAnimator.SetBool(IsAttacking, false);
  196.                 }
  197.                 break;
  198.  
  199.             case EnemyState.alert:
  200.                 if (!alerted){
  201.                     // StopAllCoroutines();
  202.                     if (!FlashlightController.FlashlightDisabled){
  203.                         if (isPlayerRunning){
  204.                             StartCoroutine(AlertTimer(alertDelay/3));
  205.                         }
  206.                         else if (!isPlayerRunning){
  207.                             StartCoroutine(AlertTimer(alertDelay));
  208.                         }
  209.                     }
  210.                     else if (FlashlightController.FlashlightDisabled){
  211.                         if (isPlayerRunning){
  212.                             StartCoroutine(AlertTimer(alertDelay/2));
  213.                         }
  214.                         else if (!isPlayerRunning){
  215.                             StartCoroutine(AlertTimer(alertDelay*2));  
  216.                         }
  217.                     }
  218.                 }
  219.                 if (distanceToPlayer <= viewRadius){
  220.                     if (alerted){
  221.                         roaming = false;
  222.                         lookingForPlayer = false;
  223.                         FaceTarget(player);
  224.                         StartCoroutine(FOVRoutine());
  225.                         PlayerController.currentTarget = targetPoint;
  226.                         // player.GetComponent<PlayerController>().lightMovement = false;
  227.                         if (canSeePlayer){
  228.                                 meshAgent.SetDestination(player.transform.position);
  229.                                 FaceTarget(player);
  230.                         }
  231.                         if (enemyAnimator.GetBool(IsAttacking) == true){
  232.                                 enemyAnimator.SetBool(IsAttacking, false);
  233.                         }
  234.                     }
  235.                 }
  236.                 if (!isPlayerNear){
  237.                         lookingForPlayer = false;
  238.                         behaviorState = EnemyState.looking;
  239.                 }
  240.                 if (enemyAnimator.GetBool(IsAttacking) == true){
  241.                     enemyAnimator.SetBool(IsAttacking, false);
  242.                 }              
  243.                 break;
  244.  
  245.             case EnemyState.looking:
  246.                 roaming = false;
  247.                 alerted = false;
  248.                 PlayerController.lightMovement = true;
  249.                 //only null if the player hasn't targeted another enemy since us
  250.                 if (PlayerController.currentTarget == targetPoint){
  251.                     PlayerController.currentTarget = null;
  252.                 }
  253.  
  254.                 if (!lookingForPlayer){
  255.                     Look();
  256.                 }
  257.                 if (enemyAnimator.GetBool(IsAttacking) == true){
  258.                     enemyAnimator.SetBool(IsAttacking, false);
  259.                 }
  260.                 break;
  261.  
  262.             case EnemyState.roaming:
  263.                     lookingForPlayer = false;
  264.                     alerted = false;
  265.                     RoamAround();
  266.                 if (enemyAnimator.GetBool(IsAttacking) == true){
  267.                     enemyAnimator.SetBool(IsAttacking, false);
  268.                 }
  269.                     break;
  270.  
  271.             case EnemyState.chase:
  272.             lookingForPlayer = false;
  273.             roaming = false;
  274.             alerted = false;
  275.             FieldOfViewCheck();
  276.             if (canSeePlayer){
  277.                 meshAgent.SetDestination(player.transform.position);
  278.                 FaceTarget(player);
  279.                 PlayerController.currentTarget = targetPoint;
  280.                 // player.GetComponent<PlayerController>().lightMovement = false;
  281.             }
  282.             if (enemyAnimator.GetBool(IsAttacking) == true){
  283.                     enemyAnimator.SetBool(IsAttacking, false);
  284.             }
  285.             break;
  286.  
  287.             case EnemyState.attack:
  288.                 lookingForPlayer = false;
  289.                 roaming = false;
  290.                 alerted = false;
  291.                 //attack player
  292.                 if (enemyAnimator.GetBool(IsAttacking) == false){
  293.                     enemyAnimator.SetBool(IsAttacking, true);
  294.                 }
  295.                 meshAgent.SetDestination(player.transform.position);
  296.                 FaceTarget(player);
  297.                 PlayerController.currentTarget = targetPoint;
  298.                 // player.GetComponent<PlayerController>().lightMovement = false;
  299.             break;
  300.  
  301.             case EnemyState.dodge:
  302.                 //dodge player attack
  303.             break;
  304.         }
  305.     }
  306.  
  307.     private void FaceTarget(GameObject target)
  308.     {
  309.         Vector3 dir = target.transform.position - transform.position;
  310.         Quaternion lookRotation = Quaternion.LookRotation(dir);
  311.         Vector3 rotation = Quaternion.Lerp(transform.rotation, lookRotation, Time.deltaTime * turnSpeed).eulerAngles;
  312.         transform.rotation = Quaternion.Euler(0f, rotation.y, 0f);
  313.     }
  314.  
  315.     private IEnumerator FOVRoutine(){
  316.         FieldOfViewCheck();
  317.         yield return null;
  318.     }
  319.  
  320.     private void FieldOfViewCheck()
  321.     {
  322.         rangeChecks = Physics.OverlapSphere(transform.position, viewRadius, targetMask);
  323.  
  324.         if (rangeChecks.Length !=0){
  325.             var target = rangeChecks[0].transform;
  326.             var directionToTarget = (target.position - transform.position).normalized;
  327.  
  328.             if (Vector3.Angle(transform.forward, directionToTarget) < fovAngle /2)
  329.             {
  330.                 var position = transform.position;
  331.                 var distanceToTarget = Vector3.Distance(position, target.position);
  332.                 canSeePlayer = !Physics.Raycast(position, directionToTarget, distanceToTarget, obstructionMask);
  333.             }
  334.             else
  335.                 canSeePlayer = false;
  336.         }
  337.         else if (canSeePlayer)
  338.             canSeePlayer = false;
  339.     }
  340.     private IEnumerator AlertTimer(float duration){
  341.         var wait = new WaitForSecondsRealtime(duration);
  342.         yield return wait;
  343.         alerted = true;
  344.         isPlayerNear = true;
  345.     }
  346.     private void Look(){
  347.         lookingForPlayer = true;
  348.         roaming = false;
  349.         //print ("Looking Around");
  350.         StartCoroutine(LookWait(lookDelay));
  351.     }
  352.  
  353.     private IEnumerator LookWait(float duration){
  354.         //print ("Enter");
  355.         var wait = new WaitForSecondsRealtime(duration);
  356.         yield return wait;
  357.         //print ("Exit after " + duration + " seconds.");
  358.         RandomizePoint();
  359.         behaviorState = EnemyState.roaming;
  360.     }
  361.  
  362.     private void RandomizePoint()
  363.     {
  364.         while (true)
  365.         {
  366.             randomCircle = new Vector3(Random.insideUnitCircle.x * viewRadius, 0, (Random.insideUnitCircle.y) * viewRadius);
  367.             var point = randomPointObject.transform.position + randomCircle;
  368.             var walkMask = 1 << NavMesh.GetAreaFromName("Walkable");
  369.             NavMeshHit hit;
  370.             if (NavMesh.SamplePosition(point, out hit, 0.15f, walkMask)) //is the point within 0.25 units of a NavMesh surface
  371.             {
  372.                 onMesh = true;
  373.                 randomPointObject.transform.position = point;
  374.             }
  375.             else
  376.             {
  377.                 onMesh = false;
  378.                 continue;
  379.             }
  380.  
  381.             break;
  382.         }
  383.     }
  384.  
  385.     private void RoamAround(){
  386.         lookingForPlayer = false;
  387.         roaming = true;
  388.         meshAgent.SetDestination(randomPointObject.transform.position);
  389.         FaceTarget(randomPointObject);
  390.         // // Check if we've reached the destination
  391.         if (meshAgent.pathPending) return;
  392.         if (!(meshAgent.remainingDistance <= meshAgent.stoppingDistance)) return;
  393.         if (meshAgent.velocity.sqrMagnitude <= 0.025f)
  394.         {
  395.             behaviorState = EnemyState.looking;
  396.         }
  397.     }
  398. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement