| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- using Sirenix.OdinInspector;
- using UnityEngine;
- public class chargeDownward : MonoBehaviour
- {
- // 状态枚举
- private enum MovementState { Idle, Dashing, Breaking, Rising }
- private MovementState currentState = MovementState.Idle;
- public Enemy owner;
- private AttackController attackController;
- private Rigidbody rb;
- [Header("移动参数")]
- [LabelText("目标上升高度")]
- private float Height;
- public float targetRiseHeight = 8f;
- public float maxRiseHeight = 16f;
- public float upHeight = 4f;
- [LabelText("冲刺速度")]
- public float dashSpeed = 1f;
- public float riseSpeed = 1f;
- [LabelText("冷却时间")]
- public float breakDuration = 0.5f;
- [LabelText("冲刺方向")]
- public Vector3 dashDirection = Vector3.down;
- public Vector3 riseDirection = Vector3.up;
- [LabelText("能否冲刺")]
- public bool canDash = true;
- [LabelText("是否使用本地坐标")]
- public bool useLocalSpace = true;
- [Header("力控制")]
- [LabelText("阻尼系数")]
- public float drag = 0.5f;
- [LabelText("最大速度")]
- public float maxSpeed = 30f;
- public GameObject foot;
- public GameObject waterRing;
- [Header("碰撞检测")]
- [LabelText("地面层")]
- public LayerMask groundLayer;
- [LabelText("检测半径")]
- public float groundCheckRadius = 0.2f;
- [LabelText("地面检测点")]
- public Transform groundCheckPoint;
- private Vector3 riseStartPosition; // 记录上升起始位置,用于计算相对高度
- private float breakStartTime; // 冷却开始时间
- private Vector3 targetVelocity = Vector3.zero;
- void Awake()
- {
- Height = targetRiseHeight;
- attackController = GetComponent<AttackController>();
- rb = GetComponent<Rigidbody>();
- }
- public void Update()
- {
- if (owner.state != CharacterState.Attack)
- {
- StopAllMovements();
- if (owner.state == CharacterState.Rise)
- {
- foot.GetComponent<Foot>().trigGroundList.Clear();
- foot.SetActive(false);
- }
- else
- {
- foot.SetActive(true);
- }
- return;
- }
- switch (currentState)
- {
- case MovementState.Idle:
- if (attackController.isAttackTriggerOn && canDash)
- {
- StartDash();
- currentState = MovementState.Dashing;
- }
- else if (!canDash && !attackController.isAttackTriggerOn)
- {
- StartRise();
- currentState = MovementState.Rising;
- }
- break;
- case MovementState.Dashing:
- UpdateDashing();
- break;
- case MovementState.Breaking:
- UpdateBreaking();
- break;
- case MovementState.Rising:
- UpdateRising();
- break;
- }
- }
- private void FixedUpdate()
- {
- if (currentState == MovementState.Dashing || currentState == MovementState.Rising)
- {
- Vector3 desiredVelocity = targetVelocity - rb.velocity;
- float forceMagnitude = (currentState == MovementState.Dashing) ? dashSpeed : riseSpeed;
- Vector3 force = desiredVelocity * forceMagnitude;
- if (rb.velocity.magnitude < maxSpeed || Vector3.Dot(rb.velocity, targetVelocity) < 0)
- {
- rb.AddForce(force, ForceMode.Force);
- }
- }
- }
- public void StartDash()
- {
- foot.SetActive(false);
- if (IsDashing) return;
- IsDashing = true;
- canDash = false;
- Vector3 direction = useLocalSpace ? transform.TransformDirection(dashDirection) : dashDirection;
- if (direction.y > 0) direction.y = -direction.y; // 确保向下
- targetVelocity = direction * dashSpeed;
- }
- private void UpdateDashing()
- {
- if (!IsDashing) return;
- if (IsGrounded())
- {
- if (targetRiseHeight < maxRiseHeight)
- {
- targetRiseHeight += upHeight;
- owner.flyHeight = targetRiseHeight;
- dashSpeed *= targetRiseHeight/Height;
- riseSpeed *= 1+(targetRiseHeight / Height-1)/2f;
- }
- owner.ani.speed = 3.33f / breakDuration;
- owner.ani.Play("attack_fall", 0, 0);
- IsDashing = false;
- isBreaking = true;
- breakStartTime = Time.time;
- currentState = MovementState.Breaking;
- rb.velocity = Vector3.zero;
- return;
- }
- //Vector3 direction = useLocalSpace ? transform.TransformDirection(dashDirection) : dashDirection;
- //if (direction.y > 0) direction.y = -direction.y;
- //targetVelocity = direction * dashSpeed;
- }
- public void StartRise()
- {
- if (IsRising || isBreaking) return;
- riseStartPosition = transform.position; // 记录上升起点
- IsRising = true;
- owner.ani.speed = 1f;
- owner.ani.Play("walk", 0, 0);
- Vector3 direction = useLocalSpace ? transform.TransformDirection(riseDirection) : riseDirection;
- if (direction.y < 0) direction.y = -direction.y; // 确保向上
- targetVelocity = direction * riseSpeed;
- }
- private void UpdateRising()
- {
- if (!IsRising) return;
- float heightDifference = Mathf.Abs(transform.position.y - targetRiseHeight);
- if (heightDifference < 1f)
- {
- IsRising = false;
- canDash = true;
- currentState = MovementState.Idle;
- owner.ChangeState(CharacterState.Idle);
- foot.GetComponent<Foot>().trigGroundList.Clear();
- foot.SetActive(true);
- return;
- }
- //// 持续更新上升方向和速度
- //Vector3 direction = useLocalSpace ? transform.TransformDirection(riseDirection) : riseDirection;
- //if (direction.y < 0) direction.y = -direction.y;
- //targetVelocity = direction * riseSpeed;
- }
- private void UpdateBreaking()
- {
- if (!isBreaking) return;
- if (Time.time - breakStartTime >= breakDuration)
- {
- isBreaking = false;
- currentState = MovementState.Idle;
- }
- }
- public void StopAllMovements()
- {
- IsDashing = false;
- IsRising = false;
- isBreaking = false;
- currentState = MovementState.Idle;
- }
- private bool IsGrounded()
- {
- if (Physics.CheckSphere(groundCheckPoint.position, groundCheckRadius, LayerMask.GetMask("Ground")))
- {
- GameObject Fx =PoolManager.Instantiate(waterRing);
- Fx.transform.position = new Vector3(this.transform.position.x, 0, transform.position.z);
- ParticleSystem water = Fx.GetComponent<ParticleSystem>();
- water.Play();
- }
- return Physics.CheckSphere(groundCheckPoint.position, groundCheckRadius, groundLayer);
- }
- public bool IsDashing { get; private set; }
- public bool IsRising { get; private set; }
- [ShowInInspector, ReadOnly]
- private bool isBreaking;
- }
|