Unity中Animator组件Runtime控制动画的正向和反向播放

2023-12-22 04:36

本文主要是介绍Unity中Animator组件Runtime控制动画的正向和反向播放,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        最初的想法是希望能够完全不改变美工的工作流程,通过代码解决所有问题。但是以笔者目前的认知水平还不行,还得麻烦一下美工,郁闷。

        本来以为Animator.speed这个值设置为负数就可以倒播动画了,但是实际上设置为小于0的数和0没有区别,就是等同于暂停而已。

        那么剩下就是改AnimatorState的speed了。本来以为只要获取到当前的AnimatorState就好办了,但是发现这是不可能的!你只能通过GetCurrentAnimatorStateInfo获取到当前的AnimatorStateInfo,而AnimatorStateInfo的speed值是只读的,国内国外搜了好几圈,没找到能在运行时获取AnimatorState的办法。

        那就只能麻烦美工了,如图:

        默认的AnimatorState是moveUpDown,复制这个AnimatorState,改名叫moveUpDown-1,Speed改成-1,这样虽然两个AnimatorState引用的是一个AnimatorClip,但是一个可以正向播放,一个可以反向播放。

        不过还有问题,如果使用Animator.Play(string stateName)这个重载去播放的话,每次都是重头播放,这样假如用户正向播放动画的时候,如果在动画没有播放到结尾就选择倒播,我们会发现动画不是在当前状态开始倒播,而是从结尾往回倒播,这样就会产生跳跃感。解决的办法就是,先获取当前动画已经正向播放了的归一化时间,就是Animator.normalizedTime,用1-Animator.normalizedTime这个时间作为开始反向播放的其实时间就好了,代码上用的是Animator.Play(string stateName,int layer,float normalizedTime)这个重载。反向播放改正向播放道理一样。

        代码示例如下:

using UnityEngine;public class AnimOnOff : MonoBehaviour
{[SerializeField][Header("可暂停动画")]Animator[] anims;public void Play(float playSpeed){bool enabled = !Mathf.Approximately(playSpeed, 0);if (anims != null){foreach (Animator anim in anims){if (!anim) continue;//anim.enabled = enabled;if (anim.enabled){AnimatorClipInfo clipInfo = anim.GetCurrentAnimatorClipInfo(0)[0];AnimationClip clip = clipInfo.clip;if (!clip){Debug.Log("ULog:animator clip is null.");continue;}string clipName = clip.name;if (clipName.Contains("-1")){if (playSpeed > 0){clipName = clipName.Replace("-1", "");}}else{if (playSpeed < 0){clipName += "-1";}}AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);float startPlayTime = stateInfo.normalizedTime;if(!clip.isLooping) startPlayTime = Mathf.Clamp01(startPlayTime);if (!stateInfo.IsName(clipName))startPlayTime = 1 - startPlayTime;anim.speed = Mathf.Abs(playSpeed);anim.Play(clipName, 0, startPlayTime);}}}}
}

        playSpeed形参获取的值如果是0,那么动画就停止了,如果是正数就正播,负数就倒播,绝对值的大小会影响播放速度。

        注意这行代码:

float startPlayTime = stateInfo.normalizedTime;
if(!clip.isLooping) startPlayTime = Mathf.Clamp01(startPlayTime);

        这个时间的获取是必须要手动处理一下,我一致以为normalizedTime始终会处于0到1之间,实际上是可以超过1的!!!!!

这篇关于Unity中Animator组件Runtime控制动画的正向和反向播放的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/522628

相关文章

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Python+PyQt5实现多屏幕协同播放功能

《Python+PyQt5实现多屏幕协同播放功能》在现代会议展示、数字广告、展览展示等场景中,多屏幕协同播放已成为刚需,下面我们就来看看如何利用Python和PyQt5开发一套功能强大的跨屏播控系统吧... 目录一、项目概述:突破传统播放限制二、核心技术解析2.1 多屏管理机制2.2 播放引擎设计2.3 专

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

使用Python实现文本转语音(TTS)并播放音频

《使用Python实现文本转语音(TTS)并播放音频》在开发涉及语音交互或需要语音提示的应用时,文本转语音(TTS)技术是一个非常实用的工具,下面我们来看看如何使用gTTS和playsound库将文本... 目录什么是 gTTS 和 playsound安装依赖库实现步骤 1. 导入库2. 定义文本和语言 3

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

使用DrissionPage控制360浏览器的完美解决方案

《使用DrissionPage控制360浏览器的完美解决方案》在网页自动化领域,经常遇到需要保持登录状态、保留Cookie等场景,今天要分享的方案可以完美解决这个问题:使用DrissionPage直接... 目录完整代码引言为什么要使用已有用户数据?核心代码实现1. 导入必要模块2. 关键配置(重点!)3.

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

Spring组件初始化扩展点BeanPostProcessor的作用详解

《Spring组件初始化扩展点BeanPostProcessor的作用详解》本文通过实战案例和常见应用场景详细介绍了BeanPostProcessor的使用,并强调了其在Spring扩展中的重要性,感... 目录一、概述二、BeanPostProcessor的作用三、核心方法解析1、postProcessB

kotlin中的行为组件及高级用法

《kotlin中的行为组件及高级用法》Jetpack中的四大行为组件:WorkManager、DataBinding、Coroutines和Lifecycle,分别解决了后台任务调度、数据驱动UI、异... 目录WorkManager工作原理最佳实践Data Binding工作原理进阶技巧Coroutine