chargeDownward.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. using Sirenix.OdinInspector;
  2. using UnityEngine;
  3. public class chargeDownward : MonoBehaviour
  4. {
  5. // 状态枚举
  6. private enum MovementState { Idle, Dashing, Breaking, Rising }
  7. private MovementState currentState = MovementState.Idle;
  8. public Enemy owner;
  9. private AttackController attackController;
  10. private Rigidbody rb;
  11. [Header("移动参数")]
  12. [LabelText("目标上升高度")]
  13. private float Height;
  14. public float targetRiseHeight = 8f;
  15. public float maxRiseHeight = 16f;
  16. public float upHeight = 4f;
  17. [LabelText("冲刺速度")]
  18. public float dashSpeed = 1f;
  19. public float riseSpeed = 1f;
  20. [LabelText("冷却时间")]
  21. public float breakDuration = 0.5f;
  22. [LabelText("冲刺方向")]
  23. public Vector3 dashDirection = Vector3.down;
  24. public Vector3 riseDirection = Vector3.up;
  25. [LabelText("能否冲刺")]
  26. public bool canDash = true;
  27. [LabelText("是否使用本地坐标")]
  28. public bool useLocalSpace = true;
  29. [Header("力控制")]
  30. [LabelText("阻尼系数")]
  31. public float drag = 0.5f;
  32. [LabelText("最大速度")]
  33. public float maxSpeed = 30f;
  34. public GameObject foot;
  35. public GameObject waterRing;
  36. [Header("碰撞检测")]
  37. [LabelText("地面层")]
  38. public LayerMask groundLayer;
  39. [LabelText("检测半径")]
  40. public float groundCheckRadius = 0.2f;
  41. [LabelText("地面检测点")]
  42. public Transform groundCheckPoint;
  43. private Vector3 riseStartPosition; // 记录上升起始位置,用于计算相对高度
  44. private float breakStartTime; // 冷却开始时间
  45. private Vector3 targetVelocity = Vector3.zero;
  46. void Awake()
  47. {
  48. Height = targetRiseHeight;
  49. attackController = GetComponent<AttackController>();
  50. rb = GetComponent<Rigidbody>();
  51. }
  52. public void Update()
  53. {
  54. if (owner.state != CharacterState.Attack)
  55. {
  56. StopAllMovements();
  57. if (owner.state == CharacterState.Rise)
  58. {
  59. foot.GetComponent<Foot>().trigGroundList.Clear();
  60. foot.SetActive(false);
  61. }
  62. else
  63. {
  64. foot.SetActive(true);
  65. }
  66. return;
  67. }
  68. switch (currentState)
  69. {
  70. case MovementState.Idle:
  71. if (attackController.isAttackTriggerOn && canDash)
  72. {
  73. StartDash();
  74. currentState = MovementState.Dashing;
  75. }
  76. else if (!canDash && !attackController.isAttackTriggerOn)
  77. {
  78. StartRise();
  79. currentState = MovementState.Rising;
  80. }
  81. break;
  82. case MovementState.Dashing:
  83. UpdateDashing();
  84. break;
  85. case MovementState.Breaking:
  86. UpdateBreaking();
  87. break;
  88. case MovementState.Rising:
  89. UpdateRising();
  90. break;
  91. }
  92. }
  93. private void FixedUpdate()
  94. {
  95. if (currentState == MovementState.Dashing || currentState == MovementState.Rising)
  96. {
  97. Vector3 desiredVelocity = targetVelocity - rb.velocity;
  98. float forceMagnitude = (currentState == MovementState.Dashing) ? dashSpeed : riseSpeed;
  99. Vector3 force = desiredVelocity * forceMagnitude;
  100. if (rb.velocity.magnitude < maxSpeed || Vector3.Dot(rb.velocity, targetVelocity) < 0)
  101. {
  102. rb.AddForce(force, ForceMode.Force);
  103. }
  104. }
  105. }
  106. public void StartDash()
  107. {
  108. foot.SetActive(false);
  109. if (IsDashing) return;
  110. IsDashing = true;
  111. canDash = false;
  112. Vector3 direction = useLocalSpace ? transform.TransformDirection(dashDirection) : dashDirection;
  113. if (direction.y > 0) direction.y = -direction.y; // 确保向下
  114. targetVelocity = direction * dashSpeed;
  115. }
  116. private void UpdateDashing()
  117. {
  118. if (!IsDashing) return;
  119. if (IsGrounded())
  120. {
  121. if (targetRiseHeight < maxRiseHeight)
  122. {
  123. targetRiseHeight += upHeight;
  124. owner.flyHeight = targetRiseHeight;
  125. dashSpeed *= targetRiseHeight/Height;
  126. riseSpeed *= 1+(targetRiseHeight / Height-1)/2f;
  127. }
  128. owner.ani.speed = 3.33f / breakDuration;
  129. owner.ani.Play("attack_fall", 0, 0);
  130. IsDashing = false;
  131. isBreaking = true;
  132. breakStartTime = Time.time;
  133. currentState = MovementState.Breaking;
  134. rb.velocity = Vector3.zero;
  135. return;
  136. }
  137. //Vector3 direction = useLocalSpace ? transform.TransformDirection(dashDirection) : dashDirection;
  138. //if (direction.y > 0) direction.y = -direction.y;
  139. //targetVelocity = direction * dashSpeed;
  140. }
  141. public void StartRise()
  142. {
  143. if (IsRising || isBreaking) return;
  144. riseStartPosition = transform.position; // 记录上升起点
  145. IsRising = true;
  146. owner.ani.speed = 1f;
  147. owner.ani.Play("walk", 0, 0);
  148. Vector3 direction = useLocalSpace ? transform.TransformDirection(riseDirection) : riseDirection;
  149. if (direction.y < 0) direction.y = -direction.y; // 确保向上
  150. targetVelocity = direction * riseSpeed;
  151. }
  152. private void UpdateRising()
  153. {
  154. if (!IsRising) return;
  155. float heightDifference = Mathf.Abs(transform.position.y - targetRiseHeight);
  156. if (heightDifference < 1f)
  157. {
  158. IsRising = false;
  159. canDash = true;
  160. currentState = MovementState.Idle;
  161. owner.ChangeState(CharacterState.Idle);
  162. foot.GetComponent<Foot>().trigGroundList.Clear();
  163. foot.SetActive(true);
  164. return;
  165. }
  166. //// 持续更新上升方向和速度
  167. //Vector3 direction = useLocalSpace ? transform.TransformDirection(riseDirection) : riseDirection;
  168. //if (direction.y < 0) direction.y = -direction.y;
  169. //targetVelocity = direction * riseSpeed;
  170. }
  171. private void UpdateBreaking()
  172. {
  173. if (!isBreaking) return;
  174. if (Time.time - breakStartTime >= breakDuration)
  175. {
  176. isBreaking = false;
  177. currentState = MovementState.Idle;
  178. }
  179. }
  180. public void StopAllMovements()
  181. {
  182. IsDashing = false;
  183. IsRising = false;
  184. isBreaking = false;
  185. currentState = MovementState.Idle;
  186. }
  187. private bool IsGrounded()
  188. {
  189. if (Physics.CheckSphere(groundCheckPoint.position, groundCheckRadius, LayerMask.GetMask("Ground")))
  190. {
  191. GameObject Fx =PoolManager.Instantiate(waterRing);
  192. Fx.transform.position = new Vector3(this.transform.position.x, 0, transform.position.z);
  193. ParticleSystem water = Fx.GetComponent<ParticleSystem>();
  194. water.Play();
  195. }
  196. return Physics.CheckSphere(groundCheckPoint.position, groundCheckRadius, groundLayer);
  197. }
  198. public bool IsDashing { get; private set; }
  199. public bool IsRising { get; private set; }
  200. [ShowInInspector, ReadOnly]
  201. private bool isBreaking;
  202. }