游戏开发:手把手教你实现战斗连招系统

目录

游戏开发:手把手教你实现战斗连招系统

一、前期准备

(一)工程选择

(二)素材导入

二、理论基础

三、Unity 中的具体实现步骤

(一)输入设置改造

(二)翻滚脚本改造

(三)新建战斗控制脚本

(四)脚本与动画配置

四、优化与拓展思考


在游戏开发的世界里,战斗连招系统是动作游戏的核心魅力之一,它能为玩家带来畅快淋漓的战斗体验。今天,咱们就来深入探讨一下在 Unity 引擎中,如何打造一套包含轻重击结合的战斗连招系统。

一、前期准备

(一)工程选择

你可以选择使用上期已经搭建好基础的工程,这样能基于已有成果进行开发,节省时间。要是没有上期工程,新建一个工程也没问题。

(二)素材导入

本次开发提供了资产素材包,其中包含上期视频的基础资产以及连招动作库。如果需要完整版资产,记得前往官方购买。获取素材包后,在 Unity 中直接导入.unitypackage文件。当然,你也可以根据自己的喜好,用其他动作素材进行替换。

二、理论基础

连招本质上是连续播放战斗动作的游戏机制。不同动作依据前一个动作的播放依次衔接,形成连贯的动作链条。这种动作间的连接结构可以是链形,即简单的依次顺序播放;也可以是树形,从某个动作节点出发,根据不同条件延伸出多种后续动作分支。而这些动作播放的组合方式,其实就是游戏的数据结构,再通过特定算法将它们组织起来。

在连招实现中,指令输入的时机至关重要。输入过早,后一个动作指令会覆盖前一个,导致连招错乱;输入过晚,连招看起来就会卡顿不流畅。所以,我们会采用预输入的方式,也就是在一个合适的时间窗口期内完成按键指令的处理,确保连招的顺畅性。

三、Unity 中的具体实现步骤

(一)输入设置改造

  1. 找到并双击打开input配置文件,它既关联在角色身上,也能在资产中找到。
  2. 打开配置界面后,右键添加一个action,命名为roll。接着,点击输入区域,输入shift,在筛选出的可绑定按键中选择left shift,并将控制方案设置为鼠标键盘。
  3. 把原预设的fire改名为fire1,作为轻击输入;再添加一个fire2作为重击输入。将fire1绑定到鼠标左键,fire2绑定到鼠标右键,同时分别为它们增加键盘输入J键和K键,方便操作。
  4. 完成设置后,点击保存资产并关闭窗口。

(二)翻滚脚本改造

双击打开上期编写的翻滚脚本,修改代码,使其符合新的input调用方式。这一步主要是让脚本能够正确响应新设置的输入指令。修改完成后保存脚本,回到 Unity 编辑器运行一下,检查是否能正常工作。player input会根据命名调用同一物体上的对应函数,这是一种方便的按键输入方案。

(三)新建战斗控制脚本

  1. 变量声明:在新建的脚本中,首先声明两个Animation Clip类型的动画数组,分别用于存放轻击和重击的动画。同时,声明之前编写的第三人称移动组件和Animator组件的成员变量,以便在脚本中对它们进行操作。在Start函数中,通过代码从同级对象获取这些组件。
using UnityEngine;

public class CombatController : MonoBehaviour
{
    public AnimationClip[] lightAttackClips;
    public AnimationClip[] heavyAttackClips;
    private ThirdPersonMovement movementComponent;
    private Animator animator;
    private int inputType;
    private int currentAttackIndex;
    private float invalidTime;

    void Start()
    {
        movementComponent = GetComponent<ThirdPersonMovement>();
        animator = GetComponent<Animator>();
    }
}

  1. 播放攻击函数实现:编写播放攻击函数,在函数开始时,先让角色的移动失效,避免在攻击时角色意外移动。然后根据传入的类型参数(区分轻击还是重击)和当前攻击索引,从对应的动画数组中找到合适的动画剪辑。对于轻击,攻击索引可以采用累加的方式,这样就能按顺序播放不同的轻击动画;而对于重击(终结技),则让连招索引归零,重新开始连招计数。最后,使用Animator直接播放获取到的动画剪辑,并记录动画的时长。

void PlayAttackAnimation(int type, float transitionTime)
{
    movementComponent.enabled = false;
    AnimationClip clip;
    if (type == 1) // 假设1代表轻击
    {
        clip = lightAttackClips[currentAttackIndex];
        currentAttackIndex = (currentAttackIndex + 1) % lightAttackClips.Length;
    }
    else // 假设其他值代表重击
    {
        clip = heavyAttackClips[currentAttackIndex];
        currentAttackIndex = 0;
    }
    animator.Play(clip.name, 0, 0);
    invalidTime = clip.length;
}

  1. Update函数实现:在Update函数中,首先让失效时间不断减少,当失效时间减少到零时,恢复移动组件的生效状态,同时将连招计数归零,让角色回到可正常操作的状态。接着,判断是否有预存的输入数值。如果有,再判断当前时间是否在动画结束前的 0.4 秒内(这个 0.4 秒就是预输入的窗口时间,可根据实际需求调整),并且输入对应的动画剪辑在数组范围内,满足这些条件就调用攻击动画函数。

void Update()
{
    if (invalidTime > 0)
    {
        invalidTime -= Time.deltaTime;
        if (invalidTime <= 0)
        {
            movementComponent.enabled = true;
            currentAttackIndex = 0;
        }
    }
    if (inputType != 0)
    {
        float remainingTime = animator.GetCurrentAnimatorStateInfo(0).length - animator.GetCurrentAnimatorStateInfo(0).normalizedTime * animator.GetCurrentAnimatorStateInfo(0).length;
        if (remainingTime <= 0.4f && remainingTime >= 0)
        {
            PlayAttackAnimation(inputType, 0.2f);
            inputType = 0;
        }
    }
}

  1. 获取输入函数编写:为了获取input system中的输入,我们还需要编写OnFire1OnFire2函数,分别对应轻击和重击的输入。在函数中,将输入类型保存到inputType变量中。

public void OnFire1()
{
    inputType = 1;
}

public void OnFire2()
{
    inputType = 2;
}

(四)脚本与动画配置

  1. 将编写好的战斗控制脚本添加到主角对象上。
  2. 在脚本的属性面板中,把准备好的轻击和重击动画剪辑分别添加到对应的动画数组中。例如,准备了四个轻击动画和四个重击动画,就依次将它们配置到lightAttackClipsheavyAttackClips数组里。
  3. 打开主角的Animator Controller,把用到的所有动作都拖进去,然后逐个将这些动作与站立移动状态连接起来。这样设置后,攻击动画播放完成后,角色就能回归到正常的站立移动融合状态。

四、优化与拓展思考

目前在自由控制模式下,角色在攻击时方向不能改变,这是因为直接禁用了移动组件。优化方法可以通过改造禁用逻辑,利用布尔值变量来控制是否同步动画参数,从而实现攻击时角色方向的灵活调整。不过,这部分内容就留给大家根据实际项目需求去探索和实现啦。

战斗连招的实现方式多种多样,不同的游戏项目有不同的需求,所以并没有放之四海而皆准的完美方案。希望通过这篇博客,能让你对战斗连招系统的开发有更清晰的认识,帮助你在游戏开发的道路上迈出坚实的一步!要是你在开发过程中遇到了其他难题,欢迎随时交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值