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;
}
}
}