using UnityEngine; namespace BehaviorDesigner.Runtime.Tasks.Movement { [TaskDescription("Flee from the target specified using the Unity NavMesh.")] [TaskCategory("Movement")] [HelpURL("http://www.opsive.com/assets/BehaviorDesigner/Movement/documentation.php?id=4")] [TaskIcon("Assets/Behavior Designer Movement/Editor/Icons/{SkinColor}FleeIcon.png")] public class ActionFlee : Action { [Tooltip("The speed of the agent")] public SharedFloat speed; [Tooltip("Angular speed of the agent")] public SharedFloat angularSpeed; [Tooltip("The agent has fleed when the square magnitude is greater than this value")] public SharedFloat fleedMinDistance = 5; [Tooltip("The agent has fleed when the square magnitude is greater than this value")] public SharedFloat fleedMaxDistance = 15; [Tooltip("The distance to look ahead when fleeing")] public SharedFloat lookAheadDistance = 5; [Tooltip("The transform that the agent is fleeing from")] public SharedTransform targetTransform; [Tooltip("If target is null then use the target position")] public SharedVector3 targetPosition; // True if the target is a transform private bool dynamicTarget; // A cache of the NavMeshAgent private UnityEngine.AI.NavMeshAgent navMeshAgent; private float fleedDistance; public override void OnAwake() { // cache for quick lookup navMeshAgent = gameObject.GetComponent(); } public override void OnStart() { if (navMeshAgent == null) { navMeshAgent = gameObject.GetComponent(); } // the target is dynamic if the target transform is not null and has a valid dynamicTarget = (targetTransform != null && targetTransform.Value != null); fleedDistance = UnityEngine.Random.Range(fleedMinDistance.Value, fleedMaxDistance.Value); // set the speed, angular speed, and destination then enable the agent navMeshAgent.speed = speed.Value; navMeshAgent.angularSpeed = angularSpeed.Value; navMeshAgent.enabled = true; navMeshAgent.destination = Target(); } // Flee from the target. Return success once the agent has fleed the target by moving far enough away from it // Return running if the agent is still fleeing public override TaskStatus OnUpdate() { if (!navMeshAgent.pathPending && Vector3.SqrMagnitude(transform.position - Target()) > fleedDistance) { return TaskStatus.Success; } navMeshAgent.destination = FleePosition(); return TaskStatus.Running; } public override void OnEnd() { // Disable the nav mesh navMeshAgent.enabled = false; } // return targetPosition if targetTransform is null private Vector3 Target() { if (dynamicTarget) { return targetTransform.Value.position; } return targetPosition.Value; } // Flee in the opposite direction private Vector3 FleePosition() { return transform.position + (transform.position - Target()).normalized * lookAheadDistance.Value; } // Reset the public variables public override void OnReset() { speed = 10; angularSpeed = 10; lookAheadDistance = 5; } } }