Part7:Create Dash State(P34)
1:效果和操作
效果:按shift实现冲刺效果
操作:新增timer计时器和cooldown冷却时间字段
思路:当按下leftshift键时,切换为dashstate,此时令statetimer(状态持续时间)与dash Duration冲刺持续时间相同,且在此状态内以player.dashSpeed * player.facingDir速度进行移动,当statetimer<0即为表示冲刺结束后转化为idle状态
2:代码改变
//Player代码改变
public float dashSpeed;//冲刺速度
public float dashDuration;//持续时间
public PlayerDashState dashState { get; private set; }
private void Awake()
{
dashState = new PlayerDashState(this, stateMachine, "Dash");
}
public float timer;//计时器
public float cooldown;//冷却时间
private void Update()//在mano中update会自动刷新但其他没有mano的不会故,需要在这个updata中调用其他脚本中的函数stateMachine.currentState.update以实现 //stateMachine中的update
{
stateMachine.currentState.Update();//反复调用CurrentState的Update函数
timer -= Time.deltaTime;//计时器
}
//新增PLayerDashState
public class PlayerDashState : PlayerState
{
public PlayerDashState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
{
}
public override void Enter()
{
base.Enter();
stateTimer = player.dashDuration;//冲刺持续时间
player.SetVelocity(player.dashSpeed * player.facingDir, rb.velocity.y);
}
public override void Exit()
{
base.Exit();
player.SetVelocity(0, rb.velocity.y);
}
public override void Update()
{
base.Update();
if (stateTimer < 0)
{
stateMachine.ChangeState(player.idleState);
}
}
}
//PlayerState代码改变
protected float stateTimer;
public virtual void Update()
{
stateTimer -= Time.deltaTime;
}
public virtual void Enter()
{
player.anim.SetBool(animBoolName, true);//此案例则因为new PlayerDashState(this, stateMachine, "Dash"),使得播放PlayerDash动画
}
public virtual void Exit()
{
player.anim.SetBool(animBoolName, false);
}
//PlayerGroundState代码改变
public override void Update()
{
base.Update();
if(Input.GetKeyDown(KeyCode.LeftShift))
{
stateMachine.ChangeState(player.dashState);
}
}
3:效果图(图2,3为退出和进入条件,图片资源为69-72)
Part8:Improving Dash State(P35)
1:效果和操作
同part7
2:代码改变
//PlayerGroundState代码改变
//删除dash动作检测
if(player.IsGroundDetected()==false)
{
stateMachine.ChangeState(player.airState);
}
//非地面接触状态则转化为air状态,防止move行为在空中发生
//Player代码改变
[Header("Dash Info")]
[SerializeField] private float dashCooldown;//固定冷却时间
private float dashUsageTimer;//冷却时间计时器
public float dashSpeed;//冲刺速度
public float dashDuration;//持续时间
public float dashDir { get; private set; }//冲刺朝向
private void Update()
{
stateMachine.currentState.Update();//反复调用CurrentState的Update函数
CheckForDashInput();//冲刺指令检测
}
public void CheckForDashInput()
{
dashUsageTimer -= Time.deltaTime;//冷却时间
if (Input.GetKeyDown(KeyCode.LeftShift) && dashUsageTimer < 0)
{//只有按下shift和冷却时间到了才可以进行dash
dashUsageTimer = dashCooldown;
dashDir = Input.GetAxisRaw("Horizontal");
//dashdir有输入则按照输入方向作为朝向,如果没有则以人物本身的facingdir作为朝向
if (dashDir == 0)
{
dashDir = facingDir;
}
stateMachine.ChangeState(dashState);
}
}
//PlayerDashState代码改变
public override void Update()
{
base.Update();
player.SetVelocity(player.dashSpeed * player.dashDir, 0);
//此处facingdir换成dashdir
if (stateTimer < 0)//状态持续时间结束则转化
{
stateMachine.ChangeState(player.idleState);
}