[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;
}
}
}
最终效果如下,实现跳跃,位移以及空中转向。
Unity战斗系统 文章被收录于专栏
Unity战斗系统实现笔记