ActionSurroundAlert.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. using BehaviorDesigner.Runtime.Tasks;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.AI;
  6. using BehaviorDesigner.Runtime.Tasks.EnemyAI;
  7. namespace BehaviorDesigner.Runtime.Tasks
  8. {
  9. [TaskDescription("近战警戒。前后游走")]
  10. [TaskCategory("YLSJ")]
  11. public class ActionSurroundAlert : NavMeshMovementBase
  12. {
  13. [Tooltip("围绕的目标")]
  14. public SharedTransform target;
  15. [Tooltip("警戒的最小总时间")]
  16. public SharedFloat alertMinTime = 6.0f;
  17. [Tooltip("警戒的最大总时间")]
  18. public SharedFloat alertMaxTime = 12.0f;
  19. [Tooltip("在当前位置后退的最小距离(比如攻击距离是2,后退的距离是1,怪物和人物之间的实际距离是2+1=3,实际距离不要超过alertDistance距离)")]
  20. public SharedFloat backMinDis = 1;
  21. [Tooltip("在当前位置后退的最大距离(比如攻击距离是2,后退的距离是3,怪物和人物之间的实际距离是2+3=5,实际距离不要超过alertDistance距离)")]
  22. public SharedFloat backMaxDis = 3;
  23. [Tooltip("警戒的最大范围,超过这个范围则进行追逐)")]
  24. public SharedFloat alertDistance = 6;
  25. [Tooltip("停留的最小时间(后退完成/围绕完成 都会停留一小段时间)")]
  26. public SharedFloat stayMinTime = 0.5f;
  27. [Tooltip("停留的最大时间(后退完成/围绕完成 都会停留一小段时间)")]
  28. public SharedFloat stayMaxTime = 1.0f;
  29. [Tooltip("围绕片断的最小时间")]
  30. public SharedFloat aroundFragmentMinTime = 2.0f;
  31. [Tooltip("围绕片断的最大时间")]
  32. public SharedFloat aroundFragmentMaxTime = 5.0f;
  33. [Tooltip("旋转速度(看向目标的旋转速度)")]
  34. public float rotationToTargetSpeed = 3;
  35. /// <summary>
  36. /// 出生地的警戒范围 (从出生地算,超出这个范围则不再追击目标)
  37. /// </summary>
  38. private float liveAlertDistance = 0;
  39. private float attackDistance = 0;
  40. /// <summary>
  41. /// 是否后退中
  42. /// </summary>
  43. private bool backing = true;
  44. /// <summary>
  45. /// 是否顺时针围绕
  46. /// </summary>
  47. private int clockwiseAround = 1;
  48. private float curAroundTotalTime = 0;
  49. private float curStayTime = 0;
  50. private float curAroundFragmentTime = 0;
  51. private float curBackDis = 0;
  52. private BehaviorTree behaviorTree = null;
  53. private Role role = null;
  54. private bool bSeek = false;
  55. public override void OnAwake()
  56. {
  57. base.OnAwake();
  58. behaviorTree = gameObject.GetComponent<BehaviorTree>();
  59. role = gameObject.GetComponent<Role>();
  60. }
  61. public override void OnStart()
  62. {
  63. base.OnStart();
  64. liveAlertDistance = (float)behaviorTree.GetVariable("liveAlertDistance").GetValue();
  65. attackDistance = (float)behaviorTree.GetVariable("attackDistance").GetValue();
  66. curAroundTotalTime = Random.Range(alertMinTime.Value, alertMaxTime.Value);
  67. backing = true;
  68. bSeek = false;
  69. m_NavMeshAgent.component.updateRotation = false;//禁用旋转
  70. m_NavMeshAgent.component.isStopped = false;
  71. Vector3 dir = target.Value.position - m_NavMeshAgent.component.transform.position;
  72. dir.Normalize();
  73. curBackDis = Random.Range(backMinDis.Value, backMaxDis.Value);
  74. Vector3 backPos = m_NavMeshAgent.component.transform.position - dir * curBackDis;
  75. SetDestination(backPos);
  76. }
  77. public override TaskStatus OnUpdate()
  78. {
  79. // 目标死亡
  80. if (target.Value == null)
  81. {
  82. return TaskStatus.Success;
  83. }
  84. // 时间到达
  85. curAroundTotalTime -= time.deltaTime;
  86. if (curAroundTotalTime <= 0)
  87. {
  88. return TaskStatus.Success;
  89. }
  90. float liveDis = Vector3.Distance(transform.position, role.mLivePos);
  91. float targetDis = Vector3.Distance(transform.position, target.Value.position);
  92. // 超出出生地活动范围
  93. if (liveDis > liveAlertDistance)
  94. {
  95. return TaskStatus.Success;
  96. }
  97. Vector3 centerPos = target.Value.position;
  98. Vector3 dir = transform.position - centerPos;
  99. float dis = Vector3.Distance(transform.position, centerPos);
  100. dir.Normalize();
  101. dir.y = 0;
  102. // 超出 警戒范围
  103. if (targetDis > alertDistance.Value)
  104. {
  105. backing = false;
  106. bSeek = true;
  107. m_NavMeshAgent.component.updateRotation = true;
  108. m_NavMeshAgent.component.speed = (float)behaviorTree.GetVariable("runSpeed").GetValue();
  109. }
  110. // 停留期间不做任何处理
  111. if (curStayTime > 0)
  112. {
  113. if (m_NavMeshAgent.component.isOnNavMesh && m_NavMeshAgent.component.isStopped != true)
  114. {
  115. m_NavMeshAgent.component.isStopped = true;
  116. }
  117. curStayTime -= time.deltaTime;
  118. return TaskStatus.Running;
  119. }
  120. else
  121. {
  122. if (m_NavMeshAgent.component.isOnNavMesh && m_NavMeshAgent.component.isStopped != false)
  123. {
  124. m_NavMeshAgent.component.isStopped = false;
  125. }
  126. }
  127. // 后退
  128. if (backing)
  129. {
  130. if (HasArrived())
  131. {
  132. backing = false;
  133. ResetAround();
  134. }
  135. }
  136. // 围绕目标
  137. else
  138. {
  139. if (bSeek == false)
  140. {
  141. // 旋转
  142. transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(-dir), rotationToTargetSpeed * Time.deltaTime);
  143. curAroundFragmentTime -= time.deltaTime;
  144. if (curAroundFragmentTime > 0)
  145. {
  146. Vector3 aroundPos = target.Value.position + dir * dis + transform.right * clockwiseAround;
  147. SetDestination(aroundPos);
  148. }
  149. else
  150. {
  151. ResetAround();
  152. }
  153. }
  154. else
  155. {
  156. if (targetDis > curBackDis + attackDistance)
  157. {
  158. Vector3 targetDir = target.Value.position - m_NavMeshAgent.component.transform.position;
  159. targetDir.Normalize();
  160. SetDestination(target.Value.position + targetDir * (curBackDis + attackDistance));
  161. }
  162. else
  163. {
  164. bSeek = false;
  165. m_NavMeshAgent.component.updateRotation = false;
  166. m_NavMeshAgent.component.speed = (float)behaviorTree.GetVariable("moveSpeed").GetValue();
  167. }
  168. }
  169. }
  170. return TaskStatus.Running;
  171. }
  172. /// <summary>
  173. /// 重置围绕
  174. /// </summary>
  175. private void ResetAround()
  176. {
  177. int clockwiseRan = Random.Range(0, 2);
  178. if (clockwiseRan == 0)
  179. {
  180. clockwiseAround = -1;
  181. }
  182. else
  183. {
  184. clockwiseAround = 1;
  185. }
  186. curStayTime = Random.Range(stayMinTime.Value, stayMaxTime.Value);
  187. curAroundFragmentTime = Random.Range(aroundFragmentMinTime.Value, aroundFragmentMaxTime.Value);
  188. }
  189. public override void OnEnd()
  190. {
  191. base.OnEnd();
  192. if (m_NavMeshAgent.component != null && m_NavMeshAgent.component.isOnNavMesh && role.isDie == false)
  193. {
  194. m_NavMeshAgent.component.isStopped = true;
  195. m_NavMeshAgent.component.updateRotation = true;
  196. }
  197. }
  198. }
  199. }