学习游戏制作记录(实现碰撞检测,翻转和冲刺状态)7/15

1.地面和墙面的碰撞检测

player脚本:

    [Header("Collision info")]//碰撞的相关定义
    [SerializeField] private Transform groundCheck;//玩家对象的一个子对象,负责对碰撞的检测
    [SerializeField] private float groundCheckDistance;//地面碰撞检测的距离
    [SerializeField] private Transform wallCheck;
    [SerializeField] private float wallCheckDistance;//同上
    [SerializeField] private LayerMask whatIsground;//图层,需要自己添加一个ground图层并设置平台的图层为Ground

public bool isGroundDetected() => Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckDistance, whatIsground);//检测bool值的定义,可以在状态里调用

    public void OnDrawGizmos()
    {
        Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y - groundCheckDistance));
        Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x + wallCheckDistance, wallCheck.position.y));
    }//调试功能方便我们确定检测的距离

PlayerGroundedState脚本:

修改函数:

        if(Input.GetKeyDown(KeyCode.Space)&&_Player.isGroundDetected())//检测是否在地面
        {
            _PlayerStateMachine.ChangeState(_Player.jumpState);
        }

PlayerAirState脚本:

修改:

        if(_Player.isGroundDetected())//当检测在地面时切换为待机状态
        {
            _PlayerStateMachine.ChangeState(_Player.idleState);
        }

那两条白线便是对地面和墙的检测距离的具象化,实践游戏是不显示的。

2.翻转功能

Player脚本:

添加定义:

    public int facingDir { get; private set; } = 1;//朝向1和-1表示
    private bool facingRight = true;//是否面向右边

构建函数:

 public void Flip()//翻转功能
 {
     facingDir = -facingDir;
     facingRight = !facingRight;//取反
     transform.Rotate(0, 180, 0);//y轴旋转
 }

 public void FlipContorller(float _x)//翻转控制函数
 {
     if(_x>0&&!facingRight)//如果朝向是1但面向左则执行翻转函数
     {
         Flip();

     }
     else if(_x<0&&facingRight)
     {
         Flip();
     }
 }

修改SetVelocity()函数:

    public void SetVelocity(float _xVelocity,float _yVelocity)
    {
        rb.velocity=new Vector2(_xVelocity, _yVelocity);
        FlipContorller(_xVelocity);//实现控制角色的翻转
    }

PlayerMoveState脚本:

Update()中:
_Player.SetVelocity(xInput * _Player.moveSpeed, rb.velocity.y);

3.冲刺功能:

主要思路:在PlayerState中设置一个计时器,再创建一个冲刺的状态,进入时我们将计时器设置为冲刺的持续时间并逐帧减小,当计时器小于0时退出,并设置速度为0。

准备好冲刺动画(Dash参数):

Player脚本:

添加定义

    public float dashSpeed = 12f;//冲刺速度
    public float dashDuration = 0.5f;//持续时间

public PlayerDashState dashState { get; private set; }//定义

Awake()中初始化:

dashState = new PlayerDashState(stateMachine, this, "Dash");

PlayerState脚本中:

protected float stateTimer;//计时器

Update()中:

stateTimer-= Time.deltaTime;//递减

创建PlayerDashState脚本,继承自PlayerState并重写和重构:

public class PlayerDashState : PlayerState
{
    public PlayerDashState(PlayerStateMachine _playerStateMachine, Player _player, string _animboolName) : base(_playerStateMachine, _player, _animboolName)
    {

    }

    public override void Enter()
    {
        base.Enter();

        stateTimer = _Player.dashDuration;//进入时设置计时器
    }

    public override void Exit()
    {
        base.Exit();

        _Player.SetVelocity(0, rb.velocity.y);//退出时重置速度
    }

    public override void Update()
    {
        base.Update();

        _Player.SetVelocity( _Player.facingDir * _Player.dashSpeed, rb.velocity.y);//冲刺时加快移动

        if(stateTimer<0)
        {
            _PlayerStateMachine.ChangeState(_Player.idleState);//计时器过了则切换至待机状态
        }
    }
}

PlayerGroundState脚本:

Update()中:
        if(Input.GetKeyDown(KeyCode.LeftShift))
        {
            _PlayerStateMachine.ChangeState(_Player.dashState);//按下左shift进入冲刺状态
        }

这样就实现了冲刺的功能了:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值