using UnityEngine;
namespace BehaviorDesigner.Runtime.Tasks.Movement
{
[TaskDescription("Wander using the Unity NavMesh.")]
[TaskCategory("Movement")]
[HelpURL("http://www.opsive.com/assets/BehaviorDesigner/Movement/documentation.php?id=9")]
[TaskIcon("Assets/Behavior Designer Movement/Editor/Icons/{SkinColor}WanderIcon.png")]
public class ActionWander : Action
{
[Tooltip("The speed of the agent")]
public SharedFloat speed;
[Tooltip("Angular speed of the agent")]
public SharedFloat angularSpeed;
[Tooltip("How far ahead of the current position to look ahead for a wander")]
public SharedFloat wanderDistance = 20;
[Tooltip("The amount that the agent rotates direction")]
public SharedFloat wanderRate = 2;
[Tooltip("The amount that the wander count,0 forver")]
public SharedInt wanderCount = 1;
///
/// 最大游荡时间
///
public float maxWanderTime = 3.0f;
// A cache of the NavMeshAgent
private UnityEngine.AI.NavMeshAgent navMeshAgent;
private int curCount = 0;
private Vector3 targetPos = Vector3.zero;
private Vector3 livePos = Vector3.zero;
private float curWanderTime = 0;
public override void OnAwake()
{
// cache for quick lookup
navMeshAgent = gameObject.GetComponent();
livePos = transform.position;
}
public override void OnStart()
{
if (navMeshAgent == null)
{
navMeshAgent = gameObject.GetComponent();
}
// 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();
curCount = wanderCount.Value;
curWanderTime = maxWanderTime;
}
// There is no success or fail state with wander - the agent will just keep wandering
public override TaskStatus OnUpdate()
{
// 游荡时间结束
curWanderTime -= Time.deltaTime;
if(curWanderTime <= 0)
{
return TaskStatus.Success;
}
if (curCount < 0)
{
return TaskStatus.Success;
}
if (navMeshAgent.destination != targetPos)
{
navMeshAgent.destination = Target();
}
else
{
if (wanderCount.Value > 0)
{
if (navMeshAgent.remainingDistance <= navMeshAgent.stoppingDistance)
{
curCount--;
}
}
}
return TaskStatus.Running;
}
public override void OnEnd()
{
// Disable the nav mesh
navMeshAgent.enabled = false;
}
// Return targetPosition if targetTransform is null
private Vector3 Target()
{
// point in a new random direction and then multiply that by the wander distance
var direction = transform.forward + Random.insideUnitSphere * wanderRate.Value;
targetPos = livePos + direction.normalized * wanderDistance.Value;
targetPos.y = navMeshAgent.destination.y;
return targetPos;
}
// Reset the public variables
public override void OnReset()
{
wanderDistance = 20;
wanderRate = 2;
maxWanderTime = 3.0f;
}
}
}