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

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("回调方法被调用!");
        }
    }


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

相关文章:

  • kubernetes存储架构之PV controller源码解读
  • 使用驱动器光盘需格式化:深度解析与数据恢复全攻略
  • OAuth 2.0
  • 2021-04-08 VSC++: 降序折半查找。
  • C语言基础——指针(4)
  • 【设备 磁盘】重要备份存放U盘的风险 + winhex 磁盘清零(清理windows无法格式化的磁盘)
  • Redis进阶篇 - 缓存穿透、缓存击穿、缓存雪崩问题及其解决方案
  • 谷歌网站收录查询,帮助您快速准确地查询网站在谷歌的收录情况的3个方法
  • Unity DOTS Baking System与Baking World
  • SU03T(语音识别播报模块)
  • 微信小程序-动画
  • python爬虫bs4库的用法
  • 【电机-概述及分类】
  • 【SQL】笛卡尔积比较收入更高的员工
  • 如何用Python监控本股市的方法
  • 【中关村在线-注册/登录安全分析报告】
  • 基于单片机的多点温度测量系统
  • 在Ubuntu下通过Docker部署NAS服务器
  • 遇到慢SQL、SQL报错,应如何快速定位问题 | OceanBase优化实践
  • Flet介绍:平替PyQt的好用跨平台Python UI框架
  • sheng的学习笔记-logback
  • 实验OSPF路由协议(课内实验)
  • 运输层和应用层之间的接口和端口有什么关系
  • Android常用C++特性之std::optional
  • 7. 无线网络安全
  • Docker全家桶:Docker Compose项目部署