Unity3D -- 自动生成动画(AnimationClip)

2023-10-30

我们一个Prefab有很多个子物体,而且当前prefab使用了大量的动画状态,假如想将该Prefab动画更改过的属性在Idle中重新更改过来,一种比较暴力方法就是直接将需要更改的属性在Idle动画中K出来,但如果动画有更改的话,我们就需要更改Idle里面的属性,操作起来比较麻烦。然后花了一天时间,查找API终于搞定代码自动生成动画,下面代码是在编辑器模式下生成动画,废话说多了,直接上代码,全套的。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
// 在Unity菜单栏设置可以点击的菜单
public class ResetAnimation : Editor {

    private Transform m_AnimatorPrefab;

    [MenuItem("Animator/ResetProperty")]
    public static void  ResetProperty()
    {
        ScriptableWizard.DisplayWizard<ChoosePrefabWizard> ("ChoosePrefab", "Apply");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.IO;

public class ChoosePrefabWizard : ScriptableWizard {

    public Transform m_AnimatorPrefab;
    public RuntimeAnimatorController m_AnimatorController;

    private const string m_AnimationPath = "Assets/Yummy/Art/Animation";
    private static Dictionary<string, bool> propertyDict = new Dictionary<string, bool>();

    static void CreateWizard()
    {
        ChoosePrefabWizard wizard = ScriptableWizard.DisplayWizard<ChoosePrefabWizard> ("choose prefab");
        wizard.minSize = new Vector2 (300, 250);
    }

    void OnWizardCreate()
    {
        AnimationClip clip = new AnimationClip ();
        clip.frameRate = 24;
        foreach (AnimationClip animationClip in m_AnimatorController.animationClips) {
            foreach (EditorCurveBinding binding in AnimationUtility.GetCurveBindings(animationClip)) {
                string pathName = binding.path + "/" + binding.propertyName;
                if (!propertyDict.ContainsKey(pathName)) {
                    string[] paths = binding.path.Split ('/');
                    string transName = paths [paths.Length - 1];
                    Transform trans = null;
                    foreach (var item in m_AnimatorPrefab.GetComponentsInChildren<Transform>()) {
                        if (item.name == transName) {
                            trans = item;
                            break;
                        }
                    }
                    if (trans == null) {
                        Debug.LogError ("can not find transform:" + transName);
                    }
                    Keyframe keyFrame = new Keyframe();
                    keyFrame.time = 0;
                    keyFrame.value = GetKeyFrameValue(trans, binding.propertyName);

                    AnimationCurve curve = new AnimationCurve ();
                    curve.AddKey (keyFrame);
                    clip.SetCurve (binding.path, binding.type, binding.propertyName, curve);
                    propertyDict.Add (pathName, true);
                }
            }

            foreach (var binding in AnimationUtility.GetObjectReferenceCurveBindings(animationClip)) {
                string pathName = binding.path + "/" + binding.propertyName;

                if (!propertyDict.ContainsKey(pathName)) {
                    string[] paths = binding.path.Split ('/');
                    string transName = paths [paths.Length - 1];
                    Transform trans = null;
                    foreach (var item in m_AnimatorPrefab.GetComponentsInChildren<Transform>()) {
                        if (item.name == transName) {
                            trans = item;
                            break;
                        }
                    }
                    if (trans == null) {
                        Debug.LogError ("can not find transform:" + transName);
                    }

                    ObjectReferenceKeyframe[] keyframes = new ObjectReferenceKeyframe[1];
                    keyframes [0] = new ObjectReferenceKeyframe ();
                    keyframes [0].time = 0;
                    keyframes [0].value = GetObjectRenferenceValue (trans, binding.propertyName);
                    AnimationUtility.SetObjectReferenceCurve (clip, binding, keyframes);
                    propertyDict.Add (pathName, true);
                }
            }
        }
        if (!Directory.Exists(m_AnimationPath)) {
            System.IO.Directory.CreateDirectory (m_AnimationPath);
        }
        AssetDatabase.CreateAsset (clip, m_AnimationPath + "/" + m_AnimatorPrefab.name + "Idle.anim");
        AssetDatabase.SaveAssets ();
    }

    /// <summary>
    /// 获取组件对应的KeyFrame值
    /// </summary>
    /// <returns>The key frame value.</returns>
    /// <param name="trans">Trans.</param>
    /// <param name="propertyName">Property name.</param>
    float GetKeyFrameValue(Transform trans, string propertyName)
    {
        if (propertyName == "m_LocalScale.x") {
            return trans.localScale.x;
        } else if (propertyName == "m_LocalScale.y") {
            return trans.localScale.y;
        } else if (propertyName == "m_LocalScale.z") {
            return trans.localScale.z;
        } else if (propertyName == "m_LocalPosition.x") {
            return trans.localPosition.x;
        } else if (propertyName == "m_LocalPosition.y") {
            return trans.localPosition.y;
        } else if (propertyName == "m_LocalPosition.z") {
            return trans.localPosition.z;
        } else if (propertyName == "localEulerAnglesRaw.x") {
            return trans.localEulerAngles.x;
        } else if (propertyName == "localEulerAnglesRaw.y") {
            return trans.localEulerAngles.y;
        } else if (propertyName == "localEulerAnglesRaw.z") {
            return trans.localEulerAngles.z;
        } else if (propertyName == "m_Size.x") {
            return trans.GetComponent<SpriteRenderer> ().size.x;
        } else if (propertyName == "m_Size.y") {
            return trans.GetComponent<SpriteRenderer> ().size.y;
        } else if (propertyName == "m_Color.a") {
            return trans.GetComponent<SpriteRenderer> ().color.a;
        } else if (propertyName == "m_Color.r") {
            return trans.GetComponent<SpriteRenderer> ().color.r;
        } else if (propertyName == "m_Color.g") {
            return trans.GetComponent<SpriteRenderer> ().color.g;
        } else if (propertyName == "m_Color.b") {
            return trans.GetComponent<SpriteRenderer> ().color.b;
        }  else if (propertyName == "m_Enabled") {
            if (trans.GetComponent<SpriteRenderer> ().enabled) {
                return 1;
            } else {
                return 0;
            }
        } else {
            Debug.LogError (propertyName + " have not doing");
            return -1;
        }
    }

    /// <summary>
    /// 获取组件的值引用
    /// </summary>
    /// <returns>The object renference value.</returns>
    /// <param name="trans">Trans.</param>
    /// <param name="propertyName">Property name.</param>
    UnityEngine.Object GetObjectRenferenceValue(Transform trans, string propertyName)
    {
        if (propertyName == "m_Sprite") {
            return trans.GetComponent<SpriteRenderer> ().sprite;
        } else {
            Debug.LogError (propertyName + " have not doing");
            return null;
        }
    }

}

ChoosePrefabWizard 打开一个窗口,你需要设置Prefab和AnimatorController,代码会自动创建一个Idle动画将更改的属性还原。
这里写图片描述
Animator Prefab和Animator Controller一定要配对,不然就会报错,如果你还更改了其他属性,你需要在GetKeyFrameValueGetObjectRenferenceValue 将更改的属性添加进去。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity3D -- 自动生成动画(AnimationClip) 的相关文章

  • 常用小工具使用记录整理

    简单记录方便后续使用 1 截图软件 FSCapture exe FSCapture最新版是款适合电脑屏幕中使用的抓屏工具 FSCapture官方版集成了图像捕捉 图像浏览以及图像编辑等功能为一体 帮助用户对截取的图形进行处理操作 并且FSC
  • JPush极光推送Unity插件iOS设备无法获取DeviceToken

    前言 最近在使用JPush进行极光推送 Unity插件GitHub地址https github com jpush jpush unity3d plugin 问题描述 但是发现了一个问题 按照官方文档操作 最终仍然无法获取DeviceTok
  • 用Sublime写html,如何配置代码自动补全功能

    Sublime安装完成后 language设置中文 步骤一 下载汉化包 就是下图这个点击下载 步骤二 打开Sublime界面 点击菜单栏 gt preferences gt Browse Packages 点击后打开了一个文件夹 返回上一层
  • word工具栏菜单栏隐藏打开的办法

    windows中打开 开始 运行 键入 winword a 然后 确定 即可恢复默认工具栏 重新打开文档
  • 游戏开发unity编辑器扩展知识系列:一个方法添加至多个MenuItem

    代码如下 用多个MenuItem标记方法就可以了 MenuItem GameObject 生成带图片的Image false 100 MenuItem Assets 生成带图片的Image static void GenImageGameO
  • 【Unity-学习-021】异步实现HTTP请求

    对Http访问操作 Unity中一般使用协程操作 但是协程有一个比较要命的要求就是所在Mono必须在场景中是激活的 所以一些操作就会被限制 所以我们就找办法替代掉协程做一些异步的操作 那就用异步方法 首先扩展一下AsyncOperation
  • Unity使用Newtonsoft报错的解决方案

    文章目录 Unity 使用 Newtonsoft 报错的解决方案 问题描述 解决方法 方法一 使用 Unity 的 Package Manager 自动导入 方法二 访问 GitHub 下载 unitypackage 文件手动导入 Unit
  • unity本地分数排行榜简单解决方案(Json)

    具体效果 大体方法 创建一个分数类Score和一个分数类的容器List
  • unity3d 输入法相关API

    Input inputString 获取输入的文字 正在打的中文是接受不到的 只有在文字写到文本框才能获取 Input imeCompositionMode 是否是激活输入框状态 on 是 Input compositionString 空
  • 短视频文案如何写,学会以下几种方法,离爆款绝对不远。

    短视频运营 视频肯定是关键 文案是对视频的一种衬托 但是也并不代表文案不重要 在短视频中的段子文案也是精心设计的 所以今天要分享的是视频介绍里的文案 是怎么炼成的 下面就跟大家讲讲如何写出比较好的视频文案 仅仅是形式 具体还是要看自己进行灵
  • unity粒子特效附上贴图后播放动画

    转自 http jingyan baidu com article f96699bbb1a0d6894f3c1b77 html 参考 http www unitymanual com thread 2993 1 1 html dsign a
  • vscode使用手册

    VS Code Visual Studio Code 是一款轻量级 跨平台的源代码编辑器 支持语法高亮 自动补全 调试 Git 版本控制等功能 下面是一些使用 VS Code 的基本操作 安装和启动 在官网上下载并安装 VS Code 打开
  • [3dsMax]2018版下拉菜单项的子菜单无法选中

    软件自身问题 安装更新补丁即可解决 不想更新补丁也可以使用键盘的方向键进行选中 补丁百度云链接 https pan baidu com s 1LDxRFwQnR0GSONuz7wcEfA 提取码 6gpk
  • 原创的 20 个 Python 自动化案例,一口一个,高效办公!

    导读 大家好 自从 发布第一篇 Python 办公自动化办公系列文章以来 目前已经马不停蹄的更新了 20 个案例 累计阅读超 10W 为了方便大家阅读学习 我将这二十个案例再次进行分类汇总 内容涵盖 Python 操作Word Excel
  • Unity3d获得android和ios设备的唯一标识

    android为mac地址 ios为advertisingIdentifier 函数都比较简单 网上也搜得到 我也就不多说了 主要是对于我们没做过安卓和IOS开发的人来说 整合进工程有各种的问题 我也就直接上网盘了点击打开链接 代码包里看得
  • Go 程序编译过程(基于 Go1.21)

    版本说明 Go 1 21 官方文档 Go 语言官方文档详细阐述了 Go 语言编译器的具体执行过程 Go1 21 版本可以看这个 https github com golang go tree release branch go1 21 sr
  • 豆瓣9.2分,250万Python新手入门的最佳选择!蟒蛇书入门到实践

    在此疾速成长的科技元年 编程就像是许多人通往无限可能世界的门票 而在编程语言的明星阵容中 Python就像是那位独领风 骚的超级巨星 以其简洁易懂的语法和强大的功能 脱颖而出 成为全球最炙手可热的编程语言之一 什么样的书能 异常 靠谱 能在
  • 卸载NotePad++/SublimeText吧:VSCode才是史上最优秀的IDE编辑器

    开源免费 免费 这应该是所有人都所希望的 而且居然是微软开源免费的 你敢信吗 vscode使用的是MIT Lisense 可随意下载 分发 商用等 下载地址 https code visualstudio com 此外 VSCode还开源
  • fckeditor编辑器改造示例:增加PRE,CODE控件

    查看专栏目录 Network 灰鸽宝典专栏主要关注服务器的配置 前后端开发环境的配置 编辑器的配置 网络服务的配置 网络命令的应用与配置 windows常见问题的解决等 文章目录 修改方法 1 修改fckconfig js文件 2 修改FC
  • Sublime Text 4 for Mac/win: 提升前端开发效率的编辑神器

    对于前端开发者来说 一个高效的代码编辑器是必不可少的工具 而Sublime Text 4作为一款著名的跨平台编辑器 不仅提供了丰富的功能 还能够极大地提升开发效率 首先 Sublime Text 4拥有强大的代码编辑功能 它支持多种编程语言

随机推荐

  • BigDecimal除法向上取整,保留 1 为小数(Java、MySQL各自写法)

    SQL写法 CEILING SUM hdd SEND OUT QTY hsl DEMAND QTY 1000 10 EXECUTE RATE Java写法 updateData getExecuteQty divide soLineQtyM
  • 阿里云实践 - HTML5断点播放m3u8视频(videojs)

    场景 HTML5页面需要通过
  • EMC问题之RE实验最优解

    EMC问题之RE实验最优解 RE实验中 最关键的可能也是最难的就是找到干扰源 进而确定是传导辐射还是空间辐射 选择对应的是一定要加屏蔽罩 哪怕环路面积很小 辐射能量还是很强 还是仅仅依靠滤波等就能解决问题 实验现象 在160MHz 80MH
  • shell中如何进行一段代码的注释

    在shell编程中 我们常常需要把一些语句注释掉 让它不执行 对单号或者少数几行shell脚本来说 在每行前面增加 符号就可以达到目的了 代码如下 cp a txt b txt mkdir p 1 2 4 2 4 6 echo ok 但如果
  • ARP欺骗和DNS劫持以及Wireshark分析

    一 实验目的 利用ettercap进行中间人攻击之ARP欺骗和DNS劫持 用Wireshark分析相关特征数据 提高对ettercap Wireshark的熟练度 同时也对中间人攻击有更加深入的认识 二 实验原理 常见的ARP欺骗方式有两种
  • 使用conda时出现Solving environment: failed with initial frozen solve. Retrying with flexible solve错误

    使用conda安装pytorch 出现了各种各样的错误 尝试了网上各种办法 最后我是这么解决的 首先添加镜像源 在终端运行以下代码 conda config add channels https mirrors tuna tsinghua
  • JDBC(数据库连接)

    JDBC 简介 什么是 JDBC JDBC 指 Java 数据库连接 是一种标准Java应用编程接口 JAVA API 用来连接 Java 编程语言和广泛的数据库 JDBC API 库包含下面提到的每个任务 都是与数据库相关的常用用法 制作
  • 学习开源项目NewBeeMall新蜂商城(1) - 初步了解与运行NewBeeMall

    文章目录 0 前言 1 NewBeeMall 新蜂商城简介 2 NewBeeMall项目配置与运行 2 1 配置MySQL数据库 2 2 配置图片资源 2 3 运行NewBeeMAll 3 NewBeeMall相关技术栈 3 1 项目原版技
  • 关于++与+=

    今天在模仿别人做购物车网页 本想用jquey的text 获取一件物品的数量 如 1 由于忽略了text 获取的是字符串 于是用了 1运算符 发现字符串也能用 输出为 11 看了模仿的网站发现他并不需要用到parseInt 函数来将字符串变为
  • 454. 4Sum II 解题记录

    题目描述 Given four lists A B C D of integer values compute how many tuples i j k l there are such that A i B j C k D l is z
  • MOSFET 导通条件

    MOSFET管是FET的一种 可以被制造为增强型或者耗尽型 P沟道或N沟道共四种类型 但实际应用的只有增强型的N沟道MOS管和增强型的P沟道MOS管 实际应用中 NMOS居多 如何分辨三个极 D极单独位于一边 而G极是第4PIN 剩下的3个
  • 支持IDE最新版!新一代报表工具FastReport VCL v6.7更新详情

    FastReport VCL是用于Delphi C Builder RAD Studio和Lazarus的报告和文档创建VCL库 它提供了可视化模板设计器 可以访问最受欢迎的数据源 报告引擎 预览 将过滤器导出为30多种格式 并可以部署到云
  • 激光条纹中心线提取算法总结和复现

    滤波 分割等预处理过程省略 输入图像为灰度图 激光条纹水平走向 目录 几何中心法 极值法 细化法 灰度重心法 法向质心法 Steger算法 几何中心法 检测出光条边界 l h 后 把两边界的中间线 l h 2作为激光条纹的中心线 inclu
  • Unity访问 FTP-SSL、FTP服务器(记录)

    1 ftps是基于ftp做了层加密 只记录ftps的访问 2 使用的工具 FluentFTP 由于直接导入unity访问文件会报安全句柄错误 因此需要以下操作 3 流程 下载FluentFTP 修改 cs文件 重新编译 dll 原因 Saf
  • 入门级详细USB移植教程——致正在为USB烦恼的朋友

    同上一篇MPU6050一样 我还是写一篇关于USB的帖子 在圈圈等玩USB的大神面前 我掌握的USB知识实在是九牛一毛 所以这篇帖子加上了入门级的修饰语 写这篇帖子主要是为了那些想快速开发USB的人 至于想深入了解USB协议 可以先学完我这
  • Access数据库注入详解

    一个人再冷酷无情 他曾经都单纯过 能有这样的结果 都是被逼的 渗透入坑学废集 前言 注入漏洞分析 网站分类 常见数据库 网站访问模型 漏洞成因 注入漏洞是怎么样形成的 常见的注入流程 注入危害 ACCESS数据库注入详解 ACCESS数据库
  • 【BZOJ】【P1816】【Cqoi2010】【扑克牌】【题解】【水题】

    传送门 http www lydsy com JudgeOnline problem php id 1816 一张图表示我wa了三次的心情 Code include
  • SpringBoot01--运行原理和自动装配原理

    SpringBoot01 一 是什么 二 SpringBoot优点 三 运行原理 四 Springboot注解 五 自动装配原理 三步 是什么 怎么做 为什么 一 是什么 1 Spring Boot是由Pivotal团队提供的全新框架 其设
  • Pycharm缓存文件太大,转移C盘中Pycharm缓存文件

    转移C盘中Pycharm缓存文件 问题 将C盘用户目录下的 Pycharm转移到E盘文件夹下 解决 找到PyCharm的D software pycharm 2019 PyCharm 2019 1 bin 添加4个 在四处红框位置处添加四行
  • Unity3D -- 自动生成动画(AnimationClip)

    我们一个Prefab有很多个子物体 而且当前prefab使用了大量的动画状态 假如想将该Prefab动画更改过的属性在Idle中重新更改过来 一种比较暴力方法就是直接将需要更改的属性在Idle动画中K出来 但如果动画有更改的话 我们就需要更