using System.Collections; using System.Collections.Generic; using UnityEngine; public struct JumpAbilityConfig { public PhysicsBody body; public PhysicsPrimitive collider; public Animator animator; public float neutralJumpSpeedY; // 垂直跳跃的基础速度 public float fowardJumpSpeedX; // 向前跳跃的水平速度 public float backwardJumpSpeedX; // 向后跳跃的水平速度(一般来说是负值) public int animJump; public int animNU; public int animFU; public int animBU; public int animND; public int animFD; public int animBD; public int animJumpEnd; } public class JumpAbility : AbilityBase { public enum Direction { Neutral, Forward, Backward } private enum State { Ready, Up, Down, End, } Direction m_Dir; PhysicsBody m_Body; PhysicsPrimitive m_Collider; Animator m_Animator; public float m_NeutralJumpSpeedY; // 垂直跳跃的基础速度 public float m_FowardJumpSpeedX; // 向前跳跃的水平速度 public float m_BackwardJumpSpeedX; // 向后跳跃的水平速度(一般来说是负值) // jump motions int m_AnimJumpStart; // on ground int m_AnimJumpNeutralUpwards; int m_AnimJumpNeutralDownwards; int m_AnimJumpFwdUpwards; int m_AnimJumpFwdDownwards; int m_AnimJumpBackUpwards; int m_AnimJumpBackDownwards; int m_AnimJumpEnd; // on ground again int m_CurAnim; State m_CurState; private List m_Triggers = new List(); public JumpAbility(JumpAbilityConfig config) { m_Body = config.body; m_Collider = config.collider; m_Animator = config.animator; m_NeutralJumpSpeedY = config.neutralJumpSpeedY; m_FowardJumpSpeedX = config.fowardJumpSpeedX; m_BackwardJumpSpeedX = config.backwardJumpSpeedX; m_AnimJumpStart = config.animJump; m_AnimJumpNeutralUpwards = config.animNU; m_AnimJumpNeutralDownwards = config.animND; m_AnimJumpFwdUpwards = config.animFU; m_AnimJumpFwdDownwards = config.animFD; m_AnimJumpBackUpwards = config.animBU; m_AnimJumpBackDownwards = config.animBD; m_AnimJumpEnd = config.animJumpEnd; // on ground again } public void SetDir(Direction dir) { m_Dir = dir; } public override void OnEnter() { base.OnEnter(); m_CurAnim = 0; OnUpdate(); } public override void OnUpdate() { AnimatorStateInfo state = m_Animator.GetCurrentAnimatorStateInfo(0); bool onGround = m_Collider.IsOnGround; float fadeDuration = 0.2f; if (onGround && m_CurAnim == m_AnimJumpNeutralDownwards && m_CurAnim != m_AnimJumpEnd) { m_Animator.CrossFade(m_AnimJumpEnd, 0); m_CurAnim = m_AnimJumpEnd; } foreach (var abilityTrigger in m_Triggers) { if (abilityTrigger.Update() && abilityTrigger.Swallow) return ; } if(onGround && m_CurAnim != m_AnimJumpStart && m_CurAnim != m_AnimJumpEnd) { m_Animator.CrossFade(m_AnimJumpStart, 0.1f); m_CurAnim = m_AnimJumpStart; return; } if(onGround && m_CurAnim == m_AnimJumpStart && state.normalizedTime >= 1f) { if (m_Dir == Direction.Neutral) m_Body.LocalVelocity = new Vector3(0, m_NeutralJumpSpeedY,0); else if(m_Dir == Direction.Forward) m_Body.LocalVelocity = new Vector3(m_FowardJumpSpeedX, m_NeutralJumpSpeedY, 0); else if(m_Dir == Direction.Backward) m_Body.LocalVelocity = new Vector3(m_BackwardJumpSpeedX, m_NeutralJumpSpeedY, 0); } bool neutral = Mathf.Approximately(m_Body.LocalVelocity.x, 0); //bool forward = m_Body.LocalVelocity.x > 0; //bool backward = m_Body.LocalVelocity.x < 0; bool forward = m_Dir == Direction.Forward; bool backward = m_Dir == Direction.Backward; bool upward = m_Body.LocalVelocity.y > 0; bool downward = m_Body.LocalVelocity.y < 0; if (neutral && upward && m_CurAnim != m_AnimJumpNeutralUpwards) { m_Animator.CrossFade(m_AnimJumpNeutralUpwards, fadeDuration); m_CurAnim = m_AnimJumpNeutralUpwards; } else if (forward && upward && m_CurAnim != m_AnimJumpFwdUpwards) { m_Animator.CrossFade(m_AnimJumpFwdUpwards, fadeDuration); m_CurAnim = m_AnimJumpFwdUpwards; } else if (backward && upward && m_CurAnim != m_AnimJumpBackUpwards) { m_Animator.CrossFade(m_AnimJumpBackUpwards, fadeDuration); m_CurAnim = m_AnimJumpBackUpwards; } else if (neutral && downward && m_CurAnim != m_AnimJumpNeutralDownwards) { m_Animator.CrossFade(m_AnimJumpNeutralDownwards, fadeDuration); m_CurAnim = m_AnimJumpNeutralDownwards; } else if (forward && downward && m_CurAnim != m_AnimJumpFwdDownwards) { m_Animator.CrossFade(m_AnimJumpFwdDownwards, fadeDuration); m_CurAnim = m_AnimJumpFwdDownwards; } else if (backward && downward && m_CurAnim != m_AnimJumpBackDownwards) { m_Animator.CrossFade(m_AnimJumpBackDownwards, fadeDuration); m_CurAnim = m_AnimJumpBackDownwards; } } public override void OnLateUpdate() { base.OnLateUpdate(); } /// /// 跳跃准备动作已经完毕 /// /// public bool IsJumpReady() { if (m_CurAnim != m_AnimJumpStart) return false; AnimatorStateInfo state = m_Animator.GetCurrentAnimatorStateInfo(0); if (state.shortNameHash == m_CurAnim && state.normalizedTime >= 1f) return true; return false; } /// /// 着地 /// /// public bool IsJumpDone() { bool onGround = m_Collider.IsOnGround; if (!onGround) return false; if (m_CurAnim == m_AnimJumpEnd) { AnimatorStateInfo state = m_Animator.GetCurrentAnimatorStateInfo(0); return state.shortNameHash == m_AnimJumpEnd && state.normalizedTime >= 1f; } return false; } public void AddTrigger(Trigger trigger) { if (trigger == null || m_Triggers.Contains(trigger)) return; m_Triggers.Add(trigger); } }