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