Advertisement
SvOzMaS

ZombieController

Dec 13th, 2016
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.40 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. [RequireComponent(typeof(NavMeshAgent))]
  5. public class ZombieController : MonoBehaviour {
  6.  
  7.     NavMeshAgent agent;                             //Agent component reference
  8.     LookAt lookAt;                                  //lookAt script reference
  9.     MoveToPoint movementController;                 //Reference to the MoveToPoint script
  10.     ZombieAnimationController animationController;  //Reference to the ZombieAnimationController script
  11.     PlayerDetector playerDetector;                  //Reference to the playerDetector script
  12.     public float maxSpeed;                          // Maximun speed the character can reach
  13.     float hSpeedSmoothing;                          //Smoothing factor of the character speed
  14.     private float nextAttackTime;                   //Time to wait until the character can attack again
  15.     public float timeBetweenAttacks;                //Time gap between attacks
  16.     public float alertDistance;                     //Distance where the character detecs the player
  17.     private float transitionTimer;                  //random timer for different state transitions
  18.  
  19.     //FSM
  20.     private int currentState;
  21.     public enum STATES { IDLE, MOVETOPLAYER, WANDER, RANDOMBEHAVIOUR, ATTACK}
  22.  
  23.     void Start() {
  24.         //Setting up references
  25.         agent = GetComponent<NavMeshAgent>();
  26.         lookAt = GetComponent<LookAt>();
  27.         movementController = GetComponent<MoveToPoint>();
  28.         animationController = GetComponent<ZombieAnimationController>();
  29.         playerDetector = GetComponentInChildren<PlayerDetector>();
  30.        
  31.         //Character starts in idle state
  32.         agent.speed = 0;
  33.         currentState = (int)STATES.IDLE;
  34.     }
  35.  
  36.     void Update() {
  37.  
  38.         // Finite state machine manager
  39.         FSMmanager();
  40.  
  41.         //Motion animations
  42.         animationController.motionAnimationsHandler(agent.speed, maxSpeed);
  43.        
  44.         //Look at the next navmesh destination point
  45.         if (lookAt)
  46.             lookAt.lookAtTargetPosition = agent.steeringTarget + transform.forward;
  47.     }
  48.  
  49.     private void calculateSpeed(float targetSpeed, float acceleration) {
  50.         agent.speed = Mathf.SmoothDamp(agent.speed, targetSpeed, ref hSpeedSmoothing, acceleration);
  51.     }
  52.  
  53.     private void FSMmanager() {
  54.  
  55.        
  56.         switch (currentState) {
  57.  
  58.             case (int)STATES.IDLE:
  59.             idleState();
  60.             Debug.Log("IDLE");
  61.             break;
  62.  
  63.             case (int)STATES.MOVETOPLAYER:
  64.             moveToPlayerState();
  65.             Debug.Log("MOVE TO PLAYER");
  66.             break;
  67.  
  68.             case (int)STATES.WANDER:
  69.             wanderState();
  70.             Debug.Log("WANDER");
  71.             break;
  72.  
  73.             case (int)STATES.RANDOMBEHAVIOUR:
  74.             randomBehaviourState();
  75.             Debug.Log("RANDOMBEHAVIOUR");
  76.             break;
  77.  
  78.             case (int)STATES.ATTACK:
  79.             attackState();
  80.             Debug.Log("ATTACK");
  81.             break;
  82.         }
  83.     }
  84.  
  85.     private void idleState() {
  86.         //Set the idle state target speed
  87.         calculateSpeed(0, 1f);
  88.  
  89.         //Transition to Move To Player
  90.         if (Vector3.Distance(transform.position, movementController.target.transform.position) < alertDistance) {
  91.             //player is close enough to detect the character
  92.             currentState = (int)STATES.MOVETOPLAYER;
  93.         }
  94.         else  {
  95.  
  96.             if (Time.time > transitionTimer) {
  97.                 /* Randomize the transitions, so the character can
  98.                    goes to randomBehaviour or to wander state */
  99.                 currentState = (Random.Range(0, 100) < 80) ? (int)STATES.WANDER : (int)STATES.RANDOMBEHAVIOUR;
  100.                 transitionTimer = Time.time + Random.Range(5, 30);
  101.             }
  102.         }
  103.     }
  104.  
  105.     private void moveToPlayerState() {
  106.         //Set the character speed to maximum speed
  107.         calculateSpeed(maxSpeed, 5f);
  108.  
  109.         //Transition to Attack
  110.         if (agent.remainingDistance <= agent.stoppingDistance + agent.radius) {
  111.             //Character is close enough to the target, so attack
  112.             currentState = (int)STATES.ATTACK;
  113.         }
  114.     }
  115.  
  116.     private void attackState() {
  117.         //Stop the player
  118.         calculateSpeed(0, 1f);
  119.  
  120.         // If the enemy has waited enough to attack again
  121.         if (Time.time > nextAttackTime && playerDetector.playerInRange && !animationController.anim.GetCurrentAnimatorStateInfo(0).IsTag("attack")) {
  122.  
  123.            
  124.             animationController.triggerAttackAnimation();
  125.             // time to wait to the next Attack
  126.             nextAttackTime = Time.time + timeBetweenAttacks;
  127.         }
  128.  
  129.         //player out of attack range and no attack animation currently playing
  130.         if (agent.remainingDistance >= agent.stoppingDistance + agent.radius && !animationController.anim.GetCurrentAnimatorStateInfo(0).IsTag("attack") && !playerDetector.playerInRange) {
  131.  
  132.             /* Randomize the transitions, so the character can
  133.             goes to randomBehaviour or to move to Player state */
  134.             currentState = (Random.Range(0, 100) < 70) ? (int)STATES.MOVETOPLAYER : (int)STATES.RANDOMBEHAVIOUR;
  135.         }
  136.     }
  137.  
  138.     private void wanderState() {
  139.         //Walk speed
  140.         calculateSpeed(2, 0.5f);
  141.         movementController.randomTarget = true;
  142.  
  143.         //Transition to move to player
  144.         if (Vector3.Distance(transform.position, movementController.target.transform.position) < alertDistance) {
  145.             movementController.randomTarget = false;
  146.             //player is close enough to detect the character
  147.             currentState = (int)STATES.MOVETOPLAYER;
  148.         }
  149.         else {
  150.             if (Time.time > transitionTimer) {
  151.                 /* Randomize the transitions, so the character can
  152.                  * keep in this state or transit to idle state */
  153.                 if (Random.Range(0, 100) < 70) {
  154.                     movementController.randomTarget = false;
  155.                     currentState = (int)STATES.IDLE;
  156.                    
  157.                 }
  158.                 transitionTimer = Time.time + Random.Range(5, 30);
  159.             }
  160.         }
  161.     }
  162.  
  163.     private void randomBehaviourState() {
  164.         //Stop the player
  165.         calculateSpeed(0, 1f);
  166.         animationController.triggerRandomBehaviourAnimation();
  167.  
  168.         //Transition to Move To Player
  169.         if (Vector3.Distance(transform.position, movementController.target.transform.position) < alertDistance) {
  170.             //player is close enough to detect the character
  171.             currentState = (int)STATES.MOVETOPLAYER;
  172.         }
  173.  
  174.         // If the animation has finished
  175.         if (!animationController.anim.GetCurrentAnimatorStateInfo(0).IsTag("randomBehaviour")) {
  176.             if (Time.time > transitionTimer) {
  177.  
  178.                 /* Randomize the transitions, so the character can
  179.                  * keep in this state or transit to idle state */
  180.  
  181.                 if (Random.Range(0, 100) < 80) {
  182.                     currentState = (int)STATES.IDLE;
  183.                 }
  184.  
  185.                 transitionTimer = (int)Time.time + Random.Range(5, 30);
  186.             }
  187.         }
  188.     }
  189.  
  190.     void OnAnimatorMove() {
  191.         // Update position based on animation movement using navigation surface height
  192.         Vector3 position = animationController.anim.rootPosition;
  193.         position.y = agent.nextPosition.y;
  194.         transform.position = position;
  195.     }
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement