仅作为学习游戏制作记录7/11

之前已经实现的功能:Player的walk,idle,dash等状态。

目前只使用了动画控制器来管理这些状态,后面会学习用有限状态机来管理这些复杂的状态。

1.回顾之前的脚本

Player脚本:代码如下:

private Rigidbody2D rb;
private Animator anim;//组件的定义


[SerializeField]private float moveSpeed;
[SerializeField]private float jumpForce;//移动速度和跳跃的高度

[Header("Dash info")]
[SerializeField] private float dashSpeed;
[SerializeField] private float dashDuration;
 private float dashTime;//冲刺速度,持续时间和计时器

[SerializeField] private float dashCooldown;
private float dashCooldownTimer;//冲刺冷却的时间和其计时器

private float xInput;//玩家x轴,-1和1

 private int facingDir=1;
 private bool facingRight=true;//玩家翻转的设置

[Header("Collision info")]
[SerializeField] private int groundCheckDistance;//离地面距离用于绘线
[SerializeField] private LayerMask whatisGround;
 private bool isGround;//检查是否处于地面图层上

update中的函数

        Movement();//移动函数
        CheckInput();//检查玩家输入
        AnimatorControllers();//动画控制函数
        CollisionChecks();//碰撞检测函数
        FlipContorller();//翻转控制函数

        dashTime -= Time.deltaTime;//冲刺的计时器
        dashCooldownTimer -= Time.deltaTime;//冲刺冷却的计时器

具体功能函数

private void CollisionChecks()
{
    isGround = Physics2D.Raycast(transform.position, Vector2.down, groundCheckDistance, whatisGround);
}//从玩家的轴心向地面画射线来检测是否在地面上,在则设置isGround为true

private void CheckInput()
{
    xInput = Input.GetAxisRaw("Horizontal");

    if (Input.GetKeyDown(KeyCode.Space))
        Jump();

    if (Input.GetKeyDown(KeyCode.LeftShift))
    {
        dashAbility();
    }
}//按空格执行跳跃,按左shift执行冲刺

private void dashAbility()
{
    if(dashCooldownTimer<0)
    {
        dashTime = dashDuration;
        dashCooldownTimer = dashCooldown;
    }
}//当冲刺计时器<0并且按下冲刺时,将二者计时器重置为持续时间和冷却时间

private void Movement()
{
    if (dashTime > 0)
    {
        rb.velocity = new Vector2(xInput * dashSpeed, 0);
    }
    else
    {
        rb.velocity = new Vector2(xInput * moveSpeed, rb.velocity.y);
    }
}//冲刺状态下速度要乘以冲刺速度,否则设置为常态速度
private void Jump()
{
    if (isGround)
    {
    rb.velocity = new Vector2(rb.velocity.x, jumpForce);

    }
}//检查是否在地面,在则可以跳跃

private void AnimatorControllers()
{
    bool isMoving = rb.velocity.x != 0;
    anim.SetBool("isMoving", isMoving);
    anim.SetBool("isGrounded", isGround);
    anim.SetFloat("yVelocity", rb.velocity.y);
    anim.SetBool("isDashing", dashTime > 0);
}//动画控制器部分的参数设置

private void Flip()
{
    facingDir = -1 * facingDir;
    facingRight = !facingRight;
    transform.Rotate(0, 180, 0);
}//翻转一次,翻转的参数各自取反,并且玩家组件旋转180°

private void FlipContorller()
{
    if (rb.velocity.x > 0 && !facingRight)
        Flip();
    else if (rb.velocity.x < 0 && facingRight)
        Flip();
}//控制何时翻转,保证朝向正确
private void OnDrawGizmos()
{
    Gizmos.DrawLine(transform.position, new Vector3(transform.position.x, transform.position.y - groundCheckDistance));
}//绘制线方便调试轴心到地面的距离

玩家控制的角色

player作为父需要挂载碰撞器,刚体,以及player的脚本。

animator作为子则负责挂载动画控制器,包括角色图片也是挂载在它上面的方便调控轴心。

2.今天学习制作攻击以及三段连击

首先制作三段攻击的动画

在动画控制器中添加如下参数:

isAttacking

comboCounter//记录连击数

isAttacking=true并且comboCounter=0过渡进入attack1动画

2,3同理。

当attack动画播完后再进入idle状态。

添加相应的代码:

[Header("Attack info")]
private bool isAttacking;
private int comboCount;//设置对应的参数

anim.SetBool("isAttacking", isAttacking);
anim.SetInteger("comboCounter", comboCount);//在AnimatorControllers()中添加

if(Input.GetKeyDown(KeyCode.Mouse0))
{
    isAttacking = true;
}//在CheckInput()中添加,当按下鼠标左键时触发攻击状态。

    public void AttackOver()
    {
        isAttacking = false;
    }//攻击结束时的那一帧调用的函数,重置isAttacking为false

在Player子对象Animator上挂载新脚本。

脚本代码如下:

private Player player;

 player = GetComponentInParent<Player>();//获取Player脚本,在初始化里调用

    private void  AnimationTrigle()
    {
        player.AttackOver();
    }//动画触发器函数,用来调用动画帧事件需要的函数

实现连击攻击

首先在player脚本中添加参数

    [SerializeField] private float comboTime=.3f;
     private float comboTimeWindow;//第一次攻击后,如果一段时间不按下第二次攻击,则重置连击数

在update()中添加

comboTimeWindow -= Time.deltaTime;//所有计时器都需要的步骤

将Check Input()中关于攻击的函数提取出来

        if(Input.GetKeyDown(KeyCode.Mouse0))
        {
            startAttackEvent();
        }

 private void startAttackEvent()
 {

     if(comboTimeWindow<0)
     {
         comboCount = 0;
     }//计时器小于0时连击数归零
     isAttacking = true;
     comboTimeWindow = comboTime;//按下攻击键开始计时
 }

完善A他tack Over()函数

    public void AttackOver()
    {
        isAttacking = false;
        comboCount++;//动画结束后连击数加1

        if(comboCount>2)
        {
            comboCount = 0;
        }//连击数超过2重置为0
    }

在attack2和attack3的最后一帧事件绑定该函数。

这样就实现攻击的三段连击

3.修复bug

我们可以移动并攻击

    private void Movement()
    {
        if(isAttacking)
        {
            rb.velocity = new Vector2(0, 0);
        }//如果在攻击状态,则设置玩家速度为0
        else if (dashTime > 0)
        {
            rb.velocity = new Vector2(xInput * dashSpeed, 0);
        }
        else
        {
            rb.velocity = new Vector2(xInput * moveSpeed, rb.velocity.y);
        }
    }

攻击时可以冲刺

    private void dashAbility()
    {
        if(dashCooldownTimer<0&&!isAttacking)//不处于攻击时才可以冲刺
        {
            dashTime = dashDuration;
            dashCooldownTimer = dashCooldown;
        }
    }

按下冲刺键时不按方向键则不动

        else if (dashTime > 0)
        {
            rb.velocity = new Vector2(facingDir * dashSpeed, 0);//xInput改为facingDir(+1,-1)
        }

角色不在地面上时不能攻击

在startAttackEvernt()中添加

if (!isGround)
    return;//当角色不在地面上并且攻击时直接返回

总结

仅仅通过动画控制器来实现状态的转变相当的复杂,因为要考虑到各种情况,如果用有限状态机则会更加的方便管理。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值