123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- using BehaviorDesigner.Runtime.Tasks.EnemyAI;
- using UnityEngine;
- using UnityEngine.AI;
- namespace BehaviorDesigner.Runtime.Tasks.Movement
- {
- [TaskDescription("Wander using the Unity NavMesh.")]
- [TaskCategory("YLSJ")]
- [HelpURL("http://www.opsive.com/assets/BehaviorDesigner/Movement/documentation.php?id=9")]
- [TaskIcon("Assets/Behavior Designer Movement/Editor/Icons/{SkinColor}WanderIcon.png")]
- public class ActionAreaWander : NavMeshMovementBase
- {
- [Tooltip("目标Object")]
- public SharedTransform targetObject;
- [Tooltip("检测目标的层级")]
- public LayerMask objectLayerMask;
- [Tooltip("观察角度")]
- public SharedFloat viewAngle = 360;
- [Tooltip("观察距离")]
- public SharedFloat viewDistance = 10;
- [Tooltip("最小游荡距离")]
- public SharedFloat minWanderDistance = 3;
- [Tooltip("最大游荡距离")]
- public SharedFloat maxWanderDistance = 7;
- [Tooltip("最小游荡持续时间")]
- public SharedFloat minWanderDuration = 2;
- [Tooltip("最大游荡的持续时间")]
- public SharedFloat maxWanderDuration = 5;
- [Tooltip("The amount that the agent rotates direction")]
- public SharedFloat wanderRate = 2;
- [Tooltip("游荡的类型 0静止1随机 2路径点巡逻,配合WanderPoints使用")]
- public SharedInt wanderType = 1;
- [Tooltip("路径点 当wanderType=2时 使用")]
- public SharedTransformList wanderPoints = null;
- private int pointIndex = 0;
- private Vector3 movePos = Vector3.zero;
- private Vector3 livePos = Vector3.zero;
- private float curWanderTime = 0;
- /// <summary>
- /// 出生最大距离
- /// </summary>
- private float liveAlertDistance = 0;
- private BehaviorTree behaviorTree = null;
- /// <summary>
- /// 是否静止中
- /// </summary>
- private bool bIdle = true;
- // 是否移动中
- private bool bMove = false;
- /// <summary>
- /// 路径点顺序/倒叙
- /// </summary>
- private bool bPointAdd = true;
- /// <summary>
- /// 是否赶往出生点
- /// </summary>
- private bool bToLive = false;
- private Role role = null;
- public override void OnAwake()
- {
- base.OnAwake();
- livePos = transform.position;
- behaviorTree = gameObject.GetComponent<BehaviorTree>();
- }
- public override void OnStart()
- {
- base.OnStart();
- role = GetComponent<Role>();
- liveAlertDistance = (float)behaviorTree.GetVariable("liveAlertDistance").GetValue();
- if (m_NavMeshAgent.component.isOnNavMesh)
- {
- m_NavMeshAgent.component.isStopped = false;
- }
- float liveDis = Vector3.Distance(transform.position, livePos);
- // 距离出生点超过最大范围 回到出生点
- if (liveDis >= liveAlertDistance)
- {
- bToLive = true;
- }
- else
- {
- bToLive = false;
- }
- curWanderTime = Random.Range(minWanderDuration.Value, maxWanderDuration.Value);
- bIdle = true;
- }
- // There is no success or fail state with wander - the agent will just keep wandering
- public override TaskStatus OnUpdate()
- {
- if (FindTarget(m_NavMeshAgent.component.transform) != null)
- {
- return TaskStatus.Success;
- }
- if (wanderType == null)
- {
- return TaskStatus.Running;
- }
- // 移动中
- if (bMove)
- {
- // 到达最小停止距离
- if (m_NavMeshAgent.component.isOnNavMesh && m_NavMeshAgent.component.remainingDistance <= m_NavMeshAgent.component.stoppingDistance)
- {
- bMove = false;
- // 静止
- bIdle = true;
- curWanderTime = Random.Range(minWanderDuration.Value, maxWanderDuration.Value);
- if (bPointAdd)
- {
- pointIndex++;
- }
- else
- {
- pointIndex--;
- }
- }
- }
- // 静止中
- else if (bIdle)
- {
- // 当前游荡时间
- curWanderTime -= Time.deltaTime;
- if (curWanderTime <= 0)
- {
- bToLive = false;
- curWanderTime = Random.Range(minWanderDuration.Value, maxWanderDuration.Value);
- // 游荡类型
- switch (wanderType.Value)
- {
- case 1:
- {
- SetRandomPos();
- }
- break;
- case 2:
- {
- SetTargetPos();
- }
- break;
- default:
- {
- // BOSS一直追人
- if (role.roleType == RoleType.Boss)
- {
- SetRandomPos();
- }
- else
- {
- // 随机移动
- SetRandomPos();
- }
- }
- break;
- }
- }
- }
- return TaskStatus.Running;
- }
- public override void OnEnd()
- {
- base.OnEnd();
- }
- /// <summary>
- /// 设置目标点
- /// </summary>
- private void SetTargetPos()
- {
- if (pointIndex < 0)
- {
- pointIndex = 1;
- bPointAdd = true;
- }
- if (pointIndex >= wanderPoints.Value.Count)
- {
- pointIndex = wanderPoints.Value.Count - 2;
- bPointAdd = false;
- }
- if (pointIndex >= 0 && pointIndex < wanderPoints.Value.Count)
- {
- movePos = wanderPoints.Value[pointIndex].position;
- SetDestination(movePos);
- bMove = true;
- bIdle = false;
- }
- }
- /// <summary>
- /// 设置随机点
- /// </summary>
- private void SetRandomPos()
- {
- int randomVal = Random.Range(0, 100);
- // 随机
- if (randomVal >= 50)
- {
- var direction = transform.forward + Random.insideUnitSphere * wanderRate.Value;
- movePos = livePos + direction.normalized * Random.Range(minWanderDistance.Value, maxWanderDistance.Value);
- SetDestination(movePos);
- bMove = true;
- bIdle = false;
- }
- }
- public Transform FindTarget(Transform selfTransform)
- {
- if (bToLive)
- {
- return null;
- }
- Transform objectFound = null;
- var hitColliders = Physics.OverlapSphere(selfTransform.position, viewDistance.Value, objectLayerMask);
- if (hitColliders != null)
- {
- float minAngle = 360;
- for (int i = 0; i < hitColliders.Length; ++i)
- {
- if (hitColliders[i].gameObject.activeSelf == false)
- {
- continue;
- }
- Role role = hitColliders[i].gameObject.GetComponent<Role>();
- if (role == null || role.isDie)
- {
- continue;
- }
- Vector3 v3Dir = hitColliders[i].transform.position - selfTransform.position;
- v3Dir.Normalize();
- float angle = Vector3.Angle(selfTransform.forward, v3Dir);
- if (angle <= viewAngle.Value * 0.5f)
- {
- if (angle < minAngle)
- {
- minAngle = angle;
- objectFound = hitColliders[i].transform;
- }
- }
- if (role.gameObject.layer == LayerMask.NameToLayer("Player"))
- {
- // 创建对话气泡框
- Role self = this.gameObject.GetComponent<Role>();
- if (self.bubType == YLBattle.SpawnPoint.BubbleType.Sight && !self.bubEnable)
- {
- SceneBubbleWindow buCmpt = self.gameObject.AddComponent<SceneBubbleWindow>();
- buCmpt.SetContent(self.bubStr);
- buCmpt.SetEnableType(self.bubType);
- self.bubEnable = true;
- }
- }
- }
- }
- targetObject.Value = objectFound;
- return objectFound;
- }
- // Reset the public variables
- public override void OnReset()
- {
- wanderRate = 2;
- minWanderDistance = 3;
- maxWanderDistance = 7;
- minWanderDuration = 2;
- maxWanderDuration = 5;
- }
- }
- }
|