黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)

文章目录

  • 今天实现的内容:
        • 新增攻击状态B
        • 新增攻击状态C
        • 连击的优化
  • BUG以及缺陷:
  • 值得注意的:

今天实现的内容:

新增攻击状态B

配置好我们的新动画,将其加入动画机。首先我们要将Rig中的如图所示的参数调整好了。
黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)_第1张图片
接下来,设置Animation页下的烘培,烘培旋转和Y轴,旋转根据Original,Y轴根据Feet。
黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)_第2张图片
要实现连续攻击,攻击B要连接到攻击A之后,在做攻击A动画时如果再次按下攻击键,就会从攻击A转换到攻击B,我们的转换条件是attack。
黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)_第3张图片
攻击A转换到攻击B要设置为优先转换。
黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)_第4张图片
最后,修改这个玩意(这叫什么来着?),我们不需要攻击A后面的收刀动作和攻击B前面的起刀动作,这样做就能“剪”掉这些不需要的动画了,也就是灰色部分。你也可以直接调整攻击B动画的起始位置。
黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)_第5张图片

新增攻击状态C

和攻击B一样,配置好动画,放到动画机中就行,转换条件和之前的也是一样的。
黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)_第6张图片

连击的优化

在我们之前的设计中,你可以通过快速连按来实现连击,我们希望玩家打出连击要更难一点,玩家只能在攻击快要结束的那一段时间内再按出攻击键才能连击,而不是随随便便就能打出连击。在接下来我们要实现通过代码来重设Attack信号。确切来说,我们将通过代码,在动画播放完挥砍动作时,将之前输入的attack信号给Reset掉,我们将要通过动画事件(Animation Events)来实现以上功能。
动画事件可以在动画资源下添加,如图所示。我们给需要做上述操作的动画资源都添加了这个叫ResetTrigger的事件,我们并没有在事件名称中具体指明reset哪个trigger,原因是我们想要复用这个事件,我们可以在String参数中指明我们要reset的trigger的名字。
黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)_第7张图片
要让动画事件得以接收,我们需要在Animator组件的同一个游戏物体上挂载一个脚本来实现具体代码。
黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)_第8张图片
代码如下:

public class AnimTriggerController : MonoBehaviour
{
     
    // 动画组件
    private Animator anim;

    private void Awake()
    {
     
        anim = GetComponent<Animator>();
    }

    // 动画事件 用于在执行时将triggerName代表的信号重置
    public void ResetTrigger(string triggerName)
    {
     
        anim.ResetTrigger(triggerName);
    }
}

老师在这里提到了在AnimTriggerController中处理事件的两种方案,一种是就在AnimTriggerController中拿到我们想要的动画组件对象,然后处理事件,另一种是AnimTriggerController不直接处理事件,而是将事件再SendMessage到PlayerController中进行处理。在这里我们采用第一种,因为已经有太多的SendMessage了。


BUG以及缺陷:

关于攻击层的权重调整,有一个缺陷,因为我们是直接调整权重为1,所以你会看到攻击动画在结束时生硬的转变到Base层的Idle,要解决这个问题,我们可以对调整权重的参数进行插值。

    // 攻击动画层权重的插值目标参数
    private float m_attackAnimWeightLerpTarget;
    
	// ...

    // 进入Attack层的动画节点attack_oneHand_A时执行的方法
    // 通过PlayerController动画机中的attack_oneHand_A节点上挂载的FSMOnEnter调用
    public void OnAttack_oneHandAEnter()
    {
     
        // ...
        
        // 修改攻击动画层权重目标值为1 具体的权重调整在OnAttack_oneHandAUpdate中执行
        m_attackAnimWeightLerpTarget = 1.0f;
    }

	// 在Attack层的动画节点attack_oneHand_A更新时执行的方法
    // 通过PlayerController动画机中的attack_oneHand_A节点上挂载的FSMOnEnter调用
    public void OnAttack_oneHandAUpdate()
    {
     
        // ...
        
        // 通过Lerp修改动画权重值
        anim.SetLayerWeight(anim.GetLayerIndex("Attack"), 
            Mathf.Lerp(anim.GetLayerWeight(anim.GetLayerIndex("Attack")), m_attackAnimWeightLerpTarget, 0.1f));
    }

    // 进入Attack层的动画节点idle时执行的方法
    // 通过PlayerController动画机中的idle节点上挂载的FSMOnEnter调用
    public void OnAttackIdleEnter()
    {
     
        // ...
        
        // 修改攻击动画层权重目标值为0
        m_attackAnimWeightLerpTarget = 0f;
    }

    // 进入Attack层的动画节点idle时执行的方法
    // 通过PlayerController动画机中的idle节点上挂载的FSMOnUpdate调用
    public void OnAttackIdleUpdate()
    {
     
        // 通过Lerp修改动画权重值
        anim.SetLayerWeight(anim.GetLayerIndex("Attack"), 
            Mathf.Lerp(anim.GetLayerWeight(anim.GetLayerIndex("Attack")), m_attackAnimWeightLerpTarget, 0.01f));
    }

OnAttackIdleUpdate是新加入的函数,对接攻击层Idle新添的FSMOnUpdate对象,为了实现和OnAttack_oneHandAUpdate一样的效果功能。
黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)_第9张图片


值得注意的:

当你想要给动画片段改名时,应该到如图所示的地方改,不能直接改动画片段的名称。
黑魂复刻游戏的玩家控制器(连续攻击及优化)——Unity随手记(2021.4.30)_第10张图片


你可能感兴趣的:(Unity随手记,游戏开发)