[RPG战斗系统] 8~9.角色跳跃状态&空中运动

跳跃状态检测与RootMotion跳跃

添加跳跃状态。

public enum PlayerState
{
    Idle,
    Move,
    Jump
}

添加跳跃的转换逻辑。

	//PlayerController
    public void ChangeState(PlayerState playerState)
    {
        switch (playerState)
        {
            case PlayerState.Idle:
                stateMachine.ChangeState<PlayerIdleState>();
                break;
            case PlayerState.Move:
                stateMachine.ChangeState<PlayerMoveState>();
                break;
            case PlayerState.Jump:
                stateMachine.ChangeState<PlayerJumpState>();
                break;
            default:
                break;
        }
    }

创建PlayerJumpState。

public class PlayerJumpState : PlayerStateBase
{
    public override void Enter()
    {
        player.PlayAnimation("Jump");
        player.PlayerModel.SetRootMotionAction(OnRootMotion);
    }

    public override void Update()
    {
        //第一次执行Update时,也许当前动画还不是Jump
        //确定当前是播放Jump动画
        AnimatorStateInfo stateInfo = player.PlayerModel.Animator.GetCurrentAnimatorStateInfo(0);
        if (stateInfo.IsName("Jump"))
        {
            //获取动画的进度
            float animationTime = stateInfo.normalizedTime;
            if (animationTime > 0.1f && animationTime <0.6f)
            {

            }
            else if(animationTime >= 0.9f)
            {
                player.ChangeState(PlayerState.Idle);
                return;
            }
        }
    }
    public override void Exit()
    {
        player.PlayerModel.ClearRootMotion();
    }
    public void OnRootMotion(Vector3 deltaPosition, Quaternion deltaRotation)
    {
        player.CharacterController.Move(deltaPosition);
    }
}
  • 在进入跳跃状态时播放跳跃状态,并将跳跃的RootMotion逻辑(和移动是一样的)传递给PlayerModel的RootMotionAction执行。
  • 在跳跃动画播放进度10%~60%时允许移动等其他逻辑,注意判断当前动画是否为跳跃动画,进入跳跃状态后,还有可能处于动画切换的过程。
  • 在跳跃动画播放进度超过90%时,切换回Idle状态。
  • 退出时清空RootMotionAction。
        //检测玩家跳跃
        if (Input.GetKeyDown(KeyCode.Space))
        {
            player.ChangeState(PlayerState.Jump);
            return;
        }

分别给PlayerMoveState,和PlayerIdleState添加跳跃状态的检测。

空中位移和旋转

首先设置空中跳跃的高度,给RootMotion位移乘一个系数。

    public void OnRootMotion(Vector3 deltaPosition, Quaternion deltaRotation)
    {
        deltaPosition.y *= player.jumpForce;
        player.CharacterController.Move(deltaPosition);
    }

对应添加跳跃力和空中位移速度的配置量。

	//PlayerController
    [Header("配置信息")]
    public float gravity = -9.8f;
    public float rotateSpeed = 8f;
    public float walk2Transition = 1f;
    public float walkSpeed = 1f;
    public float runSpeed = 1f;
    public float jumpForce = 2f;
    public float moveSpeedForJump;
    public AudioClip[] footStepAudioClips;

给跳跃进度10%~60%之前添加位移旋转逻辑,类似移动控制,并由配置量控制位移速度。

    public override void Update()
    {
        //第一次执行Update时,也许当前动画还不是Jump
        //确定当前是播放Jump动画
        AnimatorStateInfo stateInfo = player.PlayerModel.Animator.GetCurrentAnimatorStateInfo(0);
        if (stateInfo.IsName("Jump"))
        {
            //获取动画的进度
            float animationTime = stateInfo.normalizedTime;
            if (animationTime > 0.1f && animationTime <0.6f)
            {
                //处理空中位移
                float h = Input.GetAxis("Horizontal");
                float v = Input.GetAxis("Vertical");
                Vector3 input = new Vector3(h, 0, v);
                if (h!=0 || v!=0)
                {
                    //处理旋转
                    //获取相机的旋转值y
                    float y = Camera.main.transform.rotation.eulerAngles.y;
                    //让四元数和向量相乘,表示这个向量按照这个四元数所表达的角度进行旋转后得到的向量
                    Vector3 targetDir = Quaternion.Euler(0, y, 0) * input;
                    //Slerp插值
                    player.PlayerModel.transform.rotation = Quaternion.Slerp(player.PlayerModel.transform.rotation, Quaternion.LookRotation(targetDir), Time.deltaTime * player.rotateSpeed);
                }

                Vector3 dir = Camera.main.transform.TransformDirection(input);
                //Vector3 dir2 = Quaternion.Euler(0, Camera.main.transform.rotation.eulerAngles.y, 0) * new Vector3(h, 0, v);
                //player.CharacterController.Move();
                player.CharacterController.Move(player.moveSpeedForJump * Time.deltaTime * dir);

                
            }
            else if(animationTime >= 0.9f)
            {
                player.ChangeState(PlayerState.Idle);
                return;
            }
        }
    }

最终效果如下,实现跳跃,位移以及空中转向。

alt

Unity战斗系统 文章被收录于专栏

Unity战斗系统实现笔记

全部评论

相关推荐

不愿透露姓名的神秘牛友
2024-12-29 00:19
快手 Java工程师 26.0k*16.0
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务