当前位置: 首页 > article >正文

Unity学习笔记(四)如何实现角色攻击、组合攻击

前言

本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记

实现动画

首先实现角色移动的动画,动画的实现过程在第二篇,这里仅展示效果

attack1

请添加图片描述

触发攻击动画

实现脚本

接下来我们通过 Animator 编辑动画之间的过渡,以及检测是否移动(isAttacking)

在这里插入图片描述

可以攻击的条件:

  • 在地面上
  • 攻击有间隔时间
  • 攻击时不能移动

实现攻击:

  • 通过鼠标点击触发攻击
  • 判断是非为攻击状态
  • 设置攻击动画,攻击动画结束时通过事件触发

脚本新增内容 player2 ,删除了除了本功能以外的代码

public class Player2 : MonoBehaviour
{
    
    [Header("Attack info")]
    [SerializeField] private float comboTime = .3f;
    private bool isAttacking;
    private float comboTimeWindow;

    private float xInput;
    
    void Update()
    {
        ...
        comboTimeWindow -= Time.deltaTime;

        AnimatorContronllers();
        ...
    }

    private void CheckInput()
    {
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            ShartAttackEvent();
        }
        ...
    }

    private void ShartAttackEvent()
    {
        if (!isGrounded)
            return;

        isAttacking = true;
        comboTimeWindow = comboTime;
    }

    public void AttackOver()
    {
        isAttacking = false;
    }
    
    private void Movement()
    {
        xInput = Input.GetAxisRaw("Horizontal");
        // 不能边打边走
        if (isAttacking)
        {
            rb.velocity = new Vector2(0, 0);
        }
        else if (dashTime > 0)
        {
            rb.velocity = new Vector2(facingDir * dashSpeed, 0);
        }
        else
        {
            rb.velocity = new Vector2(xInput * moveSpeed, rb.velocity.y);
        }
    }
    
    private void AnimatorContronllers()
    {
        ...
        anim.SetBool("isAttacking", isAttacking);
    }
}

动画结束事件脚本

public class Player2AnimEvent : MonoBehaviour
{
    private Player2 player;

    void Start()
    {
        player = GetComponentInParent<Player2>();
    }

    private void AnimationTrigger()
    {
        player.AttackOver();
    }
}

动画添加事件

将事件脚本加到 Animator 这里

在这里插入图片描述
在这里插入图片描述

注意这里不能过度到自己
在这里插入图片描述
这里要有退出时间,使用attacking = false进行过度太突兀了。使用动画的退出时间比较平滑
在这里插入图片描述

最终效果

请添加图片描述

实现组合攻击

attack2
请添加图片描述

attack3
请添加图片描述
组合攻击条件

  • 处于攻击状态
  • 在一定时间内连续攻击
  • 组合攻击完之后我们可以循环进行组合攻击

实现条件

  • 我们需求当前是第几次攻击
  • 我们需要知道第二次攻击间隔时间

我们要设置 Animator 的参数

记得要在 attack 2 和 attack3 设置动画结束事件

在这里插入图片描述

代码变化

public class Player2 : MonoBehaviour
{
    
    [Header("Attack info")]
    [SerializeField] private float comboTime = .3f;
    private bool isAttacking;
    private float comboTimeWindow;
    public int comboCounter;
    private float xInput;
    
    void Update()
    {
        ...
        comboTimeWindow -= Time.deltaTime;

        AnimatorContronllers();
        ...
    }

    private void CheckInput()
    {
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            ShartAttackEvent();
        }
        ...
    }

    private void ShartAttackEvent()
    {
        if (!isGrounded)
            return;
        if (comboTimeWindow < 0)
            comboCounter = 0;
    
        isAttacking = true;
        comboTimeWindow = comboTime;
    }

    public void AttackOver()
    {
        comboCounter++;
        isAttacking = false;
        if (comboCounter > 2)
            comboCounter = 0;
    }
    
    private void AnimatorContronllers()
    {
        ...
        anim.SetBool("isAttacking", isAttacking);
        anim.SetInteger("comboCounter", comboCounter);
    }
}

最终效果

请添加图片描述

扩展

我们可以使用混合树来实现组合攻击吗?(混合树(Blend Tree)和子状态机(Sub-State Machine)的区别)

在Unity动画系统中,混合树(Blend Tree**)** 和 子状态机(Sub-State Machine) 是Animator Controller中两种不同的功能,它们用于组织和管理动画的播放,但它们的使用场景和目的不同。以下是两者的区别:

  1. 混合树(Blend Tree**)**

概念

  • 混合树是一种用于基于输入参数动态混合多个动画的结构。
  • 它的主要功能是通过一个或多个输入参数(如速度、角度等)来实时混合动画,从而实现平滑的动画过渡。

主要特点

  • 动态混合动画:允许根据输入参数的变化动态调整多个动画的权重,生成过渡自然的效果。
  • 主要用于运动动画:常用于需要连续平滑过渡的动画,如角色移动(行走、奔跑、慢跑)或视角调整。
  • 单个动画状态:混合树属于Animator中的单个状态,且其内部不支持条件判断或过渡关系。

使用场景

  1. 运动动画:例如,根据“速度”参数在站立、行走、跑步之间动态过渡。
  2. 方向调整:例如,结合“前后”和“左右”输入参数混合8个方向的动画(如8方向移动)。
  3. 平滑控制:任何需要基于输入参数动态调整动画权重的场景。

优点

  • 提供平滑的动画过渡。
  • 通过参数驱动,节省了状态之间过渡的复杂性。
  • 使用简单,易于可视化调整。
  1. 子状态机(Sub-State Machine)

概念

  • 子状态机是一种用于将动画状态组织成逻辑组的工具。
  • 它的主要功能是提高复杂状态机的可读性和可维护性,通过将多个动画状态归类到子状态机中。

主要特点

  • 逻辑分组:可以将多个相关的动画状态封装在一个子状态机中,便于管理。
  • 支持状态切换:子状态机内部的状态可以彼此过渡,且子状态机与外部状态之间也可以进行切换。
  • 条件驱动:通过参数和条件来控制动画状态的切换。

使用场景

  1. 复杂动画状态机:当Animator有太多的动画状态时,可以用子状态机来简化结构。例如,将“站立状态”、“战斗状态”、“跳跃状态”分别封装到子状态机中。
  2. 分层管理动画:将动画状态逻辑分层以提高可维护性和可扩展性。
  3. 模块化设计:当不同模块(如战斗、移动)有独立逻辑时,可以分别用子状态机实现。

优点

  • 简化复杂的状态机结构。
  • 增强可读性和逻辑清晰度。
  • 易于扩展,适合有大量状态的项目。
混合树 VS 子状态机

特性混合树(Blend Tree)子状态机(Sub-State Machine)功能动态混合多个动画,生成平滑的动画过渡逻辑分组多个动画状态,简化状态机管理主要用途用于基于输入参数动态调整动画(如移动速度、方向)用于管理和组织复杂的动画状态动画过渡内部动画通过参数动态混合,无需显式设置过渡状态之间通过过渡条件切换层次结构属于单个动画状态包含多个动画状态典型场景行走、跑步、转向等连续变化的动画各种独立的动画状态(如战斗、移动、跳跃等逻辑)灵活性专注于参数驱动的动态效果适合逻辑复杂的动画状态机

如何选择?
  • 选择混合树
    • 如果需要通过参数动态调整动画,例如在不同速度、角度下生成平滑过渡的运动动画。
    • 如果关注的是动画的平滑效果,而不是状态逻辑的复杂性。
  • 选择子状态机
    • 如果需要组织大量动画状态,或需要逻辑分组来简化复杂状态机的设计。
    • 如果动画状态之间的切换需要明确的条件和逻辑判断。

总结

  • 混合树专注于动画平滑过渡,解决的是“一个状态内的动画动态混合问题”。
  • 子状态机专注于状态管理和逻辑组织,解决的是“动画状态机结构复杂性的问题”。

根据具体需求决定使用哪种工具,或者在复杂项目中结合使用两者,可以达到最佳效果。


http://www.kler.cn/a/459859.html

相关文章:

  • java class类对象 加载时机
  • 《机器学习》从入门到实战——逻辑回归
  • 某小程序sign签名参数逆向分析
  • 解决chatgpt(mac app登陆)出现报错:获取您的 SSO 信息时出错
  • 鸿蒙DevEco Studio 5.0.1 Release下载npm镜像无法连接下载的解决方式:镜像地址变更为淘宝的npm 镜像,可解决
  • 鸿蒙开发:实现键值数据库存储
  • Jenkins使用记录
  • FPGA多路MIPI转FPD-Link视频缩放拼接显示,基于IMX327+FPD953架构,提供2套工程源码和技术支持
  • 使用 Scrapy 抓取网页数据
  • WebRTC:实现浏览器与移动应用的实时通信
  • 【Unity】 HTFramework框架(五十七)通过Tag、Layer批量搜索物体
  • Perl语言的软件工程
  • 自动化办公-将 Excel 的 Sheet 页拆分成单独的 Excel 文件
  • chatgpt model spec 2024
  • ubuntu20.04 调试bcache源码
  • 【C++】BC89 包含数字9的数
  • Docker搭建MySQL
  • C++ 设计模式:命令模式(Command Pattern)
  • Python 网络爬虫 全面解析
  • 基于Spring Boot的宠物领养系统的设计与实现(代码+数据库+LW)
  • 2025新一代智能终端发展全面解析:技术创新、应用拓展与产业生态演变
  • window如何将powershell以管理员身份添加到右键菜单?(按住Shift键显示)
  • git将本地项目上传到远程仓库
  • HCIA笔记10--VLAN间互访、PPPoE协议
  • 把Huggingface下载的arrow数据集转化为json格式
  • 详细讲一下Vue3中的Transition组件用法(动画)