unity 中向指定的动画片段添加动画事件,并播放动画,同时获取动画片段的时长。

Unity中的动画系统 学习Unity动画系统过程中的一些笔记 阅读详情

示例一

 
    using UnityEngine;
    using System;
 
    public static class AnimationUtils
    {
        /// <summary>
        /// 向指定的动画片段添加动画事件,并播放动画,同时获取动画片段的时长。
        /// </summary>
        /// <param name="_animator">需要添加动画事件的 Animator 组件。</param>
        /// <param name="_clipName">目标动画片段的名称。</param>
        /// <param name="_functionName">当动画事件触发时调用的方法名称。</param>
        /// <param name="_time">事件触发的时间(以秒为单位)。</param>
        /// <param name="_callback">事件触发时的回调方法。</param>
        public static void AddAnimationEventAndPlay(Animator _animator, string _clipName, string _functionName, float _time, Action _callback)
        {
            // 获取 Animator 的所有动画片段
            AnimationClip[] _clips = _animator.runtimeAnimatorController.animationClips;
 
            // 检查是否找到了动画片段
            bool clipFound = false;
 
            // 遍历所有动画片段
            for (int i = 0; i < _clips.Length; i++)
            {
                // 检查动画片段名称是否匹配
                if (_clips[i].name.Equals(_clipName))
                {
                    clipFound = true; // 标记找到动画片段
                    // 创建新的动画事件
                    AnimationEvent _event = new AnimationEvent
                    {
                        functionName = _functionName, // 设置事件调用的方法名称
                        time = _time // 设置事件触发的时间
                    };
                    _clips[i].AddEvent(_event); // 将事件添加到动画片段
                    Debug.Log($"动画事件已添加到 '{_clipName}' 动画片段,方法: '{_functionName}',时间: {_time} 秒。");
 
                    // 获取动画片段的时长
                    float clipLength = _clips[i].length;
                    Debug.Log($"动画片段 '{_clipName}' 的时长为: {clipLength} 秒。");
 
                    // 播放动画
                    _animator.Play(_clipName); // 播放指定的动画片段
 
                    // 注册回调
                    if (_callback != null)
                    {
                        _callback.Invoke(); // 调用回调方法
                    }
                    break; // 找到后退出循环
                }
            }
 
            // 如果没有找到动画片段,输出警告
            if (!clipFound)
            {
                Debug.LogWarning($"未找到名为 '{_clipName}' 的动画片段。");
            }
 
            // 重新绑定 Animator,以确保使用最新的动画事件
            _animator.Rebind();
        }
    }
 
    public class AnimationEventExample : MonoBehaviour
    {
        public Animator animator; // 关联的 Animator 组件
        public string animationClipName = "YourAnimationClip"; // 动画片段名称
        public string eventFunctionName = "YourEventFunction"; // 事件方法名称
        public float eventTime = 1.0f; // 事件触发时间
 
        void Start()
        {
            // 调用 AddAnimationEventAndPlay 方法,并传入回调
            AnimationUtils.AddAnimationEventAndPlay(animator, animationClipName, eventFunctionName, eventTime, YourCallback);
        }
 
        // 示例事件方法
        public void YourEventFunction()
        {
            Debug.Log("动画事件触发了!");
        }
 
        // 示例回调方法
        public void YourCallback()
        {
            Debug.Log("回调方法被调用!");
        }
    }

示例二


    using UnityEngine;
    using System;

    public static class AnimationUtils
    {
        /// <summary>
        /// 播放指定动画并添加动画事件,同时返回动画片段的时长。
        /// </summary>
        /// <param name="_animator">需要播放动画的 Animator 组件。</param>
        /// <param name="_clipName">目标动画片段的名称。</param>
        /// <param name="_functionName">当动画事件触发时调用的方法名称。</param>
        /// <param name="param">传递给事件方法的整数参数。</param>
        /// <param name="percent">事件触发时间的百分比(默认 1 表示动画结束时触发)。</param>
        /// <param name="callback">事件触发后的回调方法。</param>
        /// <returns>返回动画片段的时长;如果无效输入或未找到动画片段,返回 -1。</returns>
        public static float PlayAnim_AddEventAndGetDuration(Animator _animator, string _clipName, string _functionName, int param, float percent = 1, Action callback = null)
        {
            // 检查 Animator 和动画名称的有效性  
            if (_animator == null || string.IsNullOrEmpty(_clipName) || _animator.runtimeAnimatorController == null)
                return -1; // 返回 -1 表示无效输入  

            // 获取 Animator 的 RuntimeAnimatorController  
            RuntimeAnimatorController controller = _animator.runtimeAnimatorController;

            // 遍历所有动画片段  
            foreach (AnimationClip clip in controller.animationClips)
            {
                if (clip.name.Equals(_clipName, StringComparison.OrdinalIgnoreCase))
                {
                    // 创建并添加动画事件  
                    AnimationEvent aniEvent = new AnimationEvent
                    {
                        functionName = _functionName,
                        intParameter = param,
                        time = percent * clip.length
                    };
                    clip.AddEvent(aniEvent);

                    // 播放动画  
                    _animator.Play(_clipName);

                    // 调用回调函数(如果存在)  
                    callback?.Invoke();

                    return clip.length; // 返回动画片段的时长  
                }
            }

            return -1; // 如果未找到动画片段,返回 -1  
        }
    }

    public class AnimationEventExample : MonoBehaviour
    {
        public Animator animator; // 关联的 Animator 组件
        public string animationClipName = "YourAnimationClip"; // 动画片段名称
        public string eventFunctionName = "YourEventFunction"; // 事件方法名称
        public int eventParam = 0; // 传递给事件方法的参数
        public float eventPercent = 1.0f; // 事件触发时间的百分比

        void Start()
        {
            // 调用 PlayAnim_AddEventAndGetDuration 方法
            float duration = AnimationUtils.PlayAnim_AddEventAndGetDuration(animator, animationClipName, eventFunctionName, eventParam, eventPercent, YourCallback);
            Debug.Log($"动画片段 '{animationClipName}' 的时长为: {duration} 秒。");
        }

        // 示例事件方法
        public void YourEventFunction(int param)
        {
            Debug.Log($"动画事件触发了,参数: {param}");
        }

        // 示例回调方法
        public void YourCallback()
        {
            Debug.Log("回调方法被调用!");
        }
    }

在Unity中利用AnimationClip方便快捷的播放游戏动画 在Unity中我们一般要通过要通Animator类调用类中相应的触发方法,这样做的前提是必须要在动画属性面板中把这动画设置相应的触发条件(比如设置动画的触发条件为布尔值触发、数值触发等等),可以说是有点麻烦! 下面新的一种动画触发方法即将到来,也就是通过AnimationClip类进行动画的触发。(而且注意这种方法不用设置相应的动画触发条件,可以直接触发相应的动画) 代码如下: //通过Anim... 阅读详情

相关推荐

【推荐100个unity插件之2】 DoTween动画插件的安装和使用整合(最全)

摘要:DOTween动画插件使用指南 DOTween是Unity中强大的动画插件,比原生动画更便捷。安装后需进行初始化设置,通过工具菜单生成程序集。主要提供通用方法(DOTween.To)和便捷方法(如transform.DOMove)两种动画实现方式。插件支持丰富的动画设置(循环、缓动等)和事件回调(OnComplete、OnKill)。还提供动画管理功能,包括清除(DOTween.Clear)、完成(DOTween.CompleteAll)和终止(DOTween.KillAll)动画。常用功能涵盖移动、

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1万+

Unity获取Animation和Animator的时长

unity animator animation

qq_36657524的博客 4710

高速DAC设计与实现--AD9122

目录 芯片简介: 功能配置设计 高速DAC软件驱动设计 芯片简介: AD9122 是一款双通道16位高性能数模转换器(DAC),在800MSPS工作条件下其无杂散动态范围(SFDR)高达72dBc,最高可提供1200 MSPS采样速率。 高速DAC--AD9122电路原理图 硬件设计的电路原理图如上图所示,AD9122具备针对直接变频传输应用进行优化的特性,包括复数数字调制以及增益与失调补偿。DAC输出经过优化后可直接与模拟正交调制器无缝接口,便于后期使...

独木舟216的博客 1万+

Unity Animator新动画的时长获取(方法调用)

Animator新动画

m0_71624363的博客 1087

[原创]Keil工程STM32F103C8T6无缝转换到STM32F103RCT6

有个项目,老版本是STM32F103C8T6,硬件资源不够了,新版本采用STM32F103RCT6。 无缝过渡,如下: 选定芯片 宏定义改为STM32F10X_HD,USE_STDPERIPH_DRIVER 删除原有的启动汇编文件,更换为高密度器件汇编文件 时钟系统紊乱? 那得看你程序怎么写: 先看F103时钟树 int main(void) { unsigned char stat...

江东风又起 2万+

AD20/Altium designer——元器件批量命名与编号的高效技巧

本文详细介绍了在AD20/Altium Designer中实现元器件批量命名与编号的高效技巧。通过解析核心的“原理图标注”功能,从基础全局操作到进阶的按模块分区、利用标识符及合并BOM等智能方法,帮助硬件工程师彻底告别手动编号,大幅提升设计效率与文档规范性,并融入了一套完整的实战工作流。

whisky的博客 567

Unity获取Animator、Spine、DragonBones动画持续时间

Unity获取Animator、Spine、DragonBones动画持续时间

Z478942073的博客 1937

LangGraph实战:如何用循环机制优化你的LangChain Agent工作流

本文详细介绍了如何使用LangGraph的循环机制优化LangChain Agent工作流,解决传统AgentExecutor在强制工具调用、动态提示调整和多阶段循环中的局限性。通过状态机和显式状态图设计,LangGraph提供了更精准的流程控制能力,适用于复杂AI应用场景。

weixin_30316097的博客 486

Unity获得某个动画片段时间长度方法

Unity获得某个动画片段时间长度方法

weixin_46711336的博客 2092

深入解析:如何基于开源OpENer开发EtherNet/IP从站服务

通过OpENer开源库,开发者可以快速实现符合ODVA规范的EtherNet/IP从站设备,降低开发成本并提高系统灵活性。本文详细介绍了EtherNet/IP协议原理、OpENer库的特点与优缺点,以及二次开发的完整流程。通过遵循本文提供的指南,开发者可以成功构建出工业级的EtherNet/IP通信设备。

极地星辰 2993

C语言实现定时任务

例:设置定时任务,每周周X的X时X分自动重启系统 思路:将设置好的重启时间保存到本地配置文件中,设置定时器定时一分钟,每一分钟信号触发一次事件,事件函数中获取配置文件信息与当前系统时间信息,将两个时间进行时间差计算,符合条件的自动重启系统. //创建定时器函数(通过信号触发事件timer_task函数启动) int create_timer() { struct sigevent evp; int ret = 0; memset(&evp, 0, sizeof(stru

佳佳鸽的博客 5036

unity 动态获取Animator 状态机中某个动画片段的播放速度(获取到速度来计算 播放时长)

这个功能主要是因为 每个动画片段的播放速度不一样,需要获取到速度来计算 播放时长。好记性不如烂笔头。

qq_37524903的博客 2912

基于 STM32 的乒乓球发球机控制系统设计与实现

乒乓球发球机是一种能够按照预设参数自动、连续发出乒乓球的训练设备。本系统以 STM32F103C8T6 为主控核心,通过控制实现球速调节、实现落点与旋转方向控制、实现出球节奏控制,并配合 OLED 显示与按键人机交互,实现速度、频率、落点、旋转四大参数的可调发球训练。

weixin_42300449的博客 208

Unity 获取当前动画播放的帧

Unity 获取当前动画播放的帧 在Unity动画控制中,如何获得当前动画已经播放到的帧呢? 其实可以通过 clip.frameRate,clip.length,及normalizedTime来计算出具体的帧。 //当前动画机播放时长 currentTime = anim.GetCurrentAnimatorStateInfo(0).normalizedTime; //动画片段长度 float l...

qq_27677895的博客 5975

海思3403烧结、复用及mic输入

3403调试的第一步是版本烧结,版本烧结经常遇到问题,本文记录总结遇到的各种问题。

平面到立体 1353

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Unity获取正在播放动画片段的长度

项目有一个需求是动画的播放时间是随机的,要在随机的时间内播放完整段动画。需要获取动画原本的时长来调整播放速度来实现。在这里我是用的是StateMachineBehavirour,在OnStateEnter时计算动画播放速度。但是在onstateenter中通过stateinfo获取的时长并非播放片段的时长,原因时unity animator的动画融合导致,所以解决方案有两个,一个时去掉动画融合,一

selecao09的博客 1万+

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Unity中获取Animator中动画片段的时长

开发环境:Unity5.6.2 private Animator animator; public void GetLengthByName(string name) { float length = 0; AnimationClip[] clips = animator.runtimeAnimatorController.animationClips; foreach(A...

weixin_34210740的博客 4117

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Unity3D开发之设置Animator播放动画片段结束后事件设置

最近项目需求做一个效果动画,在unity自己编辑的关于Transfrom+Color Alpha变化的动画。动画编辑好后在Animator面板编辑动画切换条件。初始状态,动画进入一个空状态,当我们要展示效果的时候,就设置他的参数值Score=True,让他切换动画。切换完后再切回空状态并设置Score为false。如下图: 刚开始我一直在过度条件面板以及动画状态面板寻找可以添加的事件。但是并...

Jay W的博客 2万+

Unity中的异步编程【7】——在一个异步方法里播放了animation动画,取消任务时,如何停止动画播放

用一个异步方法来播放一个动画,正常情况是:动画播放结束时,异步方法宣告结束。那如果我提前取消这个异步任务,那在这个异步方法里面,我要怎么停止播放呢?!

穿裤子的云 2060

Unity提前获取粒子特效的播放时长

有时候需要在播放粒子特效前就清楚的知道粒子特效将播放多久 Unity的API发现ParticleSystem的duration属性不准确 这里提供一个准确的获取粒子特效的播放时长的方法 static float ParticleSystemLength(Transform transform) { var pts = transform.GetComponentsInChildren&lt...

linxinfa的专栏 5542

Unity通过Animator获取动画clip时长

///获取动画状态机animator的动画clip的播放持续时长 public static float GetClipLength(Animator animator, string clipName) { if(null== animator || string.IsNullOrEmpty(clip) || null == animator.runtimeAn...

linxinfa的专栏 1万+

unity 动画结束 后处理事件

1.GetCurrentAnimatorStateInfo方法判断动画播放。2.在动画结束帧后面加个动画事件。

qq_37524903的博客 4661

Unity功能点---Unity动画的事件(在任一帧添加关联事件)

当我们需要在动画播放到某一帧的时候同时发生一个事件,比如对人物造成伤害,或者使某些物体隐藏出现等,我们可以通过动画时长来计算帧数,然后在某个动画的某个时间进行事件的触发,这种方法通常可能会使事件不能完全对上某一帧,我们可以直接通过编辑动画在动画帧上添加事件来完成我们需要的功能。 我们在Unity里面编辑的动画可以直接在动画编辑界面处理添加事件的方法,通过外部导入的动画通常是只读的,需要找到动画点...

pq8888168的博客 3478

Unity获取Animator动画播放完成事件

获取Animator动画播放完成事件

u9king的博客 1863

Unity TimeLine实用功能讲解

这一个技术相对于其他动画系统,最大的区别就是,TimeLine针对多个游戏物体做出的一系列动画,主要用于过场动画的制作,实现电影级的那种分镜效果 注意:使用TimeLine需要2017以上的版本 在菜单栏中点Window,找到TimeLine,点开后同样也是一个面板,与Anmation类似,也是必须选中一个游戏物体后才能查看创建,其创建也可以像Animation一样先在Project窗口中先创建了...

(˶˚ ᗨ ˚˶)来康康我 7万+
上一篇: unity使用XR插件开发SteamVR项目,异常问题解决方法
下一篇: Unity 中Sirenix.OdinInspector 插件常用功能梳理
科幻之眼
博客等级 码龄9年 101粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值