Files

112 lines
5.9 KiB
C#

using UnityEngine;
namespace Invector.vCharacterController.AI.FSMBehaviour
{
#if UNITY_EDITOR
[vFSMHelpbox("Call this action to make the AI Flee from his current target, you can set the movement speed and the distance to flee", UnityEditor.MessageType.Info)]
#endif
public class vAIFlee : vStateAction
{
public override string categoryName
{
get { return "Movement/"; }
}
public override string defaultName
{
get { return "Flee"; }
}
public vAIMovementSpeed fleeSpeed = vAIMovementSpeed.Running;
public float fleeDistance = 10f;
public bool debugMode;
public bool debugFleeDirection;
public override void DoAction(vIFSMBehaviourController fsmBehaviour, vFSMComponentExecutionType executionType = vFSMComponentExecutionType.OnStateUpdate)
{
if (executionType == vFSMComponentExecutionType.OnStateUpdate)
{
Flee(fsmBehaviour);
}
else if (executionType == vFSMComponentExecutionType.OnStateEnter)
{
Flee(fsmBehaviour);
// force update path to be really fast for quick time, so the AI can react quickly and flee
fsmBehaviour.aiController.ForceUpdatePath();
}
}
protected virtual void Flee(vIFSMBehaviourController fsmBehaviour)
{
if (Time.timeScale <= 0f) return;
// FLEEING FROM DAMAGE SENDER
if (fsmBehaviour != null && fsmBehaviour.aiController.receivedDamage.isValid && fsmBehaviour.aiController.receivedDamage.lastSender != null)
{
if (fsmBehaviour.aiController.remainingDistance < 1)
{
for (int i = 1; i < 36; i++)
{
if (InTimer(fsmBehaviour, 1, "FleeTimer"))
{
if (Vector3.Distance(fsmBehaviour.aiController.targetDestination, fsmBehaviour.aiController.transform.position) < fleeDistance * 0.25f + fsmBehaviour.aiController.stopingDistance || fsmBehaviour.aiController.isInDestination)
{
if (debugMode) Debug.Log("Fleeing from damage sender");
var threatPoint = fsmBehaviour.aiController.receivedDamage.lastSender.position;
var fleeDir = fsmBehaviour.aiController.transform.position - threatPoint;
fleeDir = Quaternion.Euler(0, Random.Range(-(5 * i), 5 * i), 0) * fleeDir.normalized;
fleeDir.y = 0f;
if (debugFleeDirection) Debug.DrawRay(fsmBehaviour.aiController.transform.position, fleeDir * fleeDistance, Color.yellow, 10f);
fsmBehaviour.aiController.MoveTo(fsmBehaviour.aiController.transform.position + fleeDir * fleeDistance, fleeSpeed);
fsmBehaviour.aiController.ForceUpdatePath();
}
}
else i--;
}
}
}
// FLEEING FROM A TARGET
else if (fsmBehaviour != null && fsmBehaviour.aiController.currentTarget.transform != null)
{
for (int i = 1; i < 36; i++)
{
if (InTimer(fsmBehaviour, 1, "FleeTimer"))
{
if (Vector3.Distance(fsmBehaviour.aiController.targetDestination, fsmBehaviour.aiController.transform.position) < fleeDistance * 0.25f + fsmBehaviour.aiController.stopingDistance || fsmBehaviour.aiController.isInDestination)
{
if (debugMode) Debug.Log("Fleeing from a target");
var threatPoint = fsmBehaviour.aiController.currentTarget.transform.position;
var fleeDir = fsmBehaviour.aiController.transform.position - threatPoint;
fleeDir = Quaternion.Euler(0, Random.Range(-(5 * i), 5 * i), 0) * fleeDir.normalized;
if (debugFleeDirection) Debug.DrawRay(fsmBehaviour.aiController.transform.position, fleeDir * fleeDistance, Color.yellow, 10f);
fsmBehaviour.aiController.MoveTo(fsmBehaviour.aiController.transform.position + fleeDir * fleeDistance, fleeSpeed);
fsmBehaviour.aiController.ForceUpdatePath();
}
}
else i--;
}
}
// FLEEING WITHOUT TARGET OR DAMAGE SENDER
else if (fsmBehaviour != null)
{
for (int i = 1; i < 36; i++)
{
if (InTimer(fsmBehaviour, 1, "FleeTimer"))
{
if (Vector3.Distance(fsmBehaviour.aiController.targetDestination, fsmBehaviour.aiController.transform.position) < fleeDistance * 0.25f + fsmBehaviour.aiController.stopingDistance || fsmBehaviour.aiController.isInDestination)
{
if (debugMode) Debug.Log("Fleeing without target or damage sender");
var fleeDir = fsmBehaviour.aiController.transform.forward;
fleeDir = Quaternion.Euler(0, Random.Range(-(10 * i), 10 * (i)), 0) * fleeDir.normalized;
if (debugFleeDirection) Debug.DrawRay(fsmBehaviour.aiController.transform.position, fleeDir * fleeDistance, Color.yellow, 10f);
fsmBehaviour.aiController.MoveTo(fsmBehaviour.aiController.transform.position + fleeDir * fleeDistance, fleeSpeed);
fsmBehaviour.aiController.ForceUpdatePath();
}
}
else i--;
}
}
}
}
}