【unity游戏开发】彻底理解AnimatorStateInfo,获取真实动画长度

news/2024/10/10 6:03:54/

前言

前置知识:设置参数后,下一个循环才会切换对应动画,所以在下一个循环获取真实的动画长度
AnimatorStateInfo是结构体!值类型,要不断重复获取才是最新的

主要是自动设置trigger切换的动画自动切回上一个动画,需要在异步中等待动画结束,于是用传统方式:

//上一个动画没有退出时间,直接等一个循环就是真实动画
await UniTask.Yield(PlayerLoopTiming.Update);//上一个动画有退出时间
AnimatorStateInfo currentAm = animator.GetCurrentAnimatorStateInfo(0);
while (currentAm.normalizedTime < 1f || animator.IsInTransition(0)){await UniTask.Yield(PlayerLoopTiming.Update);}

但是我用的连击动画为了好的手感将动画结束时间提前,这就导致进入这里的currentAm 可能是上一次的攻击动画
所以直接判断上一个动画是否执行完毕

AnimatorStateInfo重要属性

  • normalizedTime :动画播放进度,播放完则是1,每次循环+1,需要注意不循环的动画可能只到9.x就切换了
  • shortNameHash:状态名字 转换成的hash值
  • length:动画时长,单位秒
  • IsName: 将字符串转为hash进行判断
    在这里插入图片描述

代码

需要约定状态名,我的枚举名和状态名相等,连击的攻击则是枚举名 + combo数 + 1,连击参数是连击状态名+Combo

private async UniTask WaitForAnimator(Animator animator){// 注意参数的设置也是下一轮才生效,所以先等一轮// 上一个动画没有退出时间,直接等一个循环就是真实动画await UniTask.Yield(PlayerLoopTiming.Update);//获取唯一状态标识var preStateKey = currentState.state.ToString().Contains("DoubleAttack") ?currentState.state.ToString() + animator.GetInteger(currentState.state.ToString() + "Combo") : lastState.state.ToString();Debug.Log(animator.GetInteger(currentState.state.ToString() + "Combo"));AnimatorStateInfo currentAm = animator.GetCurrentAnimatorStateInfo(0);//等到上一个攻击动画执行完毕while (currentAm.IsName(preStateKey)){await UniTask.Yield(PlayerLoopTiming.Update);currentAm = animator.GetCurrentAnimatorStateInfo(0);}var duration = currentAm.length;float preProcessTime = currentState.state.ToString().Contains("Attack") ? duration * 0.2f : 0; // 计算提前处理时间(动画总时长的 25%)// 等待动画完成float waitTime = duration - preProcessTime;if (waitTime > 0)await UniTask.Delay((int)(waitTime * 1000), DelayType.Realtime, PlayerLoopTiming.Update);
// 所有动画完成后切换状态ChangeState(lastBoolState);}
也可以直接保存shortNameHash作为状态名称 不推荐
private Dictionary<String, int> animalNameHashDic = new();
private async UniTask WaitForAnimator(Animator animator){//获取唯一状态标识var key = currentState.state.ToString().Contains("Attack") ?currentState.state.ToString() + GameMgr.Instance.player.ComboCounter : currentState.state.ToString();AnimatorStateInfo currentAm = animator.GetCurrentAnimatorStateInfo(0);//真实的动画长度:shortNameHash相等if (animalNameHashDic.ContainsKey(key)){// Debug.Log(currentAm.shortNameHash);while (animalNameHashDic[key] == currentAm.shortNameHash){await UniTask.Yield(PlayerLoopTiming.Update);currentAm = animator.GetCurrentAnimatorStateInfo(0);}}else{// 第一次就是真实的if (!animalNameHashDic.ContainsKey(key))animalNameHashDic.Add(key, currentAm.shortNameHash);}var duration = currentAm.length;float preProcessTime = currentState.state.ToString().Contains("Attack") ? duration * 0.2f : 0; // 计算提前处理时间(动画总时长的 25%)// 等待动画完成float waitTime = duration - preProcessTime;if (waitTime > 0)await UniTask.Delay((int)(waitTime * 1000), DelayType.Realtime, PlayerLoopTiming.Update);}

http://www.ppmy.cn/news/1536889.html

相关文章

面试--java基础

Java基础 Java 中的几种基本数据类型了解么&#xff1f;基本类型和包装类型的区别&#xff1f;包装类型的缓存机制了解么&#xff1f;成员变量与局部变量的区别&#xff1f;静态变量有什么作用&#xff1f;静态方法为什么不能调用非静态成员?重载和重写有什么区别&#xff1f…

MQ 架构设计原理与消息中间件详解(二)

### 一、RabbitMQ 如何保证消息不丢失&#xff1f; 消息不丢失可以分为三个方面进行保障&#xff1a;**生产者投递消息**、**消费者消费消息** 和 **MQ 服务器持久化**。 #### 1.1 生产者角色的消息确认机制 RabbitMQ 提供了两种方式来确保生产者投递的消息能够被成功接收&am…

MAC端VSCode code-runner插件配置 c/c++编译后 文件生成路径

请注意该配置为MAC系统上的。 window系统可以参考此方法去设置 VS Code 版本: 1.94.0 Code Runner 版本: v0.12.2 在VS Code 配置文件(settings.json)中添加/修改以下配置项。 { ..."code-runner.executorMap": {"c": "cd $dir && mkdir -…

24.2.29蓝桥杯|单位换算--8道题

本篇或者本系列文章使用蓝桥云课平台&#xff0c;借助CSDN梳理思路&#xff0c;给自己做一个电子笔记 单位换算类题目注意事项&#xff1a; 在参加蓝桥杯等编程竞赛时&#xff0c;进行单位换算是一个常见的题目类型&#xff0c;特别是涉及到数据存储和传输的问题。在处理单位换…

List的实现类

1.ArrayList&#xff08;数组&#xff09; &#xff08;1&#xff09;代码 新建学生类&#xff1a; package com.collection;public class Student {private String name;private int age;//添加构造方法 都是使用altenter快捷键public Student() {this.name name;this.age…

云原生、云计算、虚拟化概念概述

&#xff08;带着批评阅读&#xff0c;不对的请评论区补充&#xff09; 1、出现年代前后顺序 虚拟化------>云计算------>云原生 2、虚拟化 虚拟化侧重描述实现&#xff0c;开始主要是模拟、hook指令执行软件程序&#xff0c;后续出现了半虚拟化、硬件也开始有虚拟化指…

MySQL(SQLite3)数据库+Flask框架+HTML搭建个人博客网站

搭建一个博客并实现文章的发送功能&#xff0c;涉及到前后端开发和数据库操作。以下是一个简单的示例&#xff0c;使用Python的Flask框架作为后端&#xff0c;HTML和JavaScript作为前端&#xff0c;SQLite作为数据库。 1. 项目结构 my_blog/ │ ├── app.py ├── templat…

24.数据结构和算法-哈夫曼树及其应用(最优二叉树)

哈夫曼树的基本概念 哈夫曼树的构造算法 哈夫曼树构造算法的实现 理论分析 具体实现 哈夫曼编码 哈夫曼编码的性质 例题 哈夫曼编码的算法实现 哈夫曼编码的应用 文件的编码和解码