using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using KairoEngine.Core; namespace KairoEngine.CharacterSystem { /// /// Action to make a Zombie follow a target transform using one of many animation varients. /// public class ZombieFollowTargetAction : IAction { CharacterController character; Transform target; float targetDistance; int varient; float speed; float animationSpeed; bool done = false; /// /// Action that will make a character follow a target transform playing a zombie walk or run animation varient. /// /// The CharacterController performing the action /// The target Transform to be followed /// Stop following when this distance is reached /// Type of zombie animation to play. 1 to 7 are walk animations and 8 to 9 are run animations public ZombieFollowTargetAction(CharacterController character, Transform target, float targetDistance, int varient) { if(target == null) Debug.LogError("target Transform cannot be null in ZombieFollowTargetAction"); if(character == null) Debug.LogError("character CharacterController cannot be null in ZombieFollowTargetAction"); this.character = character; this.target = target; this.targetDistance = targetDistance; this.varient = varient; switch(varient) { case 1: speed = 1.2f; animationSpeed = 1f; break; case 2: speed = 1.2f; animationSpeed = 1f; break; case 3: speed = 1.2f; animationSpeed = 1f; break; case 4: speed = 1.2f; animationSpeed = 1f; break; case 5: speed = 1.2f; animationSpeed = 1f; break; case 6: speed = 1.2f; animationSpeed = 1f; break; case 7: speed = 1.2f; animationSpeed = 1f; break; case 8: speed = 2f; animationSpeed = 2f; break; case 9: speed = 2.2f; animationSpeed = 2f; break; default: speed = 1f; animationSpeed = 1f; break; } } public void Start() { character.navMeshAgent.destination = target.position; character.navMeshAgent.updatePosition = true; character.navMeshAgent.updateRotation = false; character.navMeshAgent.isStopped = false; character.navMeshAgent.speed = speed; character.navMeshAgent.stoppingDistance = targetDistance; } public void Update() { character.animator.SetFloat("ZombieMoveVarient", varient); if(Vector3.Distance(character.transform.position, target.position) > targetDistance) { character.navMeshAgent.destination = target.position; character.navMeshAgent.isStopped = false; character.navMeshAgent.updatePosition = true; } if (character.navMeshAgent == null) return; if (character.navMeshAgent.pathPending) { //Debug.Log("Calculating path"); return; } else { //Debug.Log($"Following path with {character.navMeshAgent.path.corners.Length} corners ({character.unique_name})"); } if (character.navMeshAgent.path == null) { //Debug.Log("No path"); return; } if (character.navMeshAgent.path.corners.Length == 0) { return; } if (character.navMeshAgent.isStopped) return; //Debug.Log($"Remaining distance: {character.navMeshAgent.remainingDistance} ({character.unique_name})"); if (character.navMeshAgent.remainingDistance < character.navMeshAgent.stoppingDistance) { character.navMeshAgent.isStopped = true; character.navMeshAgent.path.ClearCorners(); Stop(); return; } TurnToPoint(character.navMeshAgent.steeringTarget); Vector3 heading = character.navMeshAgent.steeringTarget - character.transform.position; float distance = heading.magnitude; Vector3 direction = heading / distance; character.animator.SetFloat("horizontal", 0); character.animator.SetFloat("vertical", animationSpeed); } private void TurnToPoint(Vector3 point) { Quaternion targetRotation = Quaternion.LookRotation (point - character.transform.position); character.animator.transform.rotation = Quaternion.Slerp (character.animator.transform.rotation, targetRotation, 100f * Time.deltaTime); } private void Stop() { character.animator.SetFloat("horizontal", 0); character.animator.SetFloat("vertical", 0); character.navMeshAgent.isStopped = true; character.navMeshAgent.updatePosition = false; character.navMeshAgent.speed = 0; character.navMeshAgent.stoppingDistance = 0; character.navMeshAgent.destination = character.transform.position; } public void End() { Stop(); done = true; } public bool IsDone() { return done; } } }