Unity中的GameObjectRecorder类录制动画

2023-11-17

Unity中的GameObjectRecorder类录制动画

记录

首先是,参考及示例视频:Unity制作战神等级的表情动画(游戏,CG,Vtuber适用),相关代码在8分16秒之后。
在观看视频之后,由于项目中有相关需求就使用了,其中的功能,这里进行一下记录,并感谢视频作者功能分享

GameObjectRecorder

GameObjectRecorder类是其中的核心代码。Unity可以看到的接口如下:

namespace UnityEditor.Animations
{
    //
    // 摘要:
    //     Records the changing properties of a GameObject as the Scene runs and saves the
    //     information into an AnimationClip.
    [NativeHeader("Editor/Src/Animation/GameObjectRecorder.h")]
    [NativeHeader("Modules/Animation/AnimationClip.h")]
    [NativeHeader("Editor/Src/Animation/EditorCurveBinding.bindings.h")]
    [NativeType]
    public class GameObjectRecorder : UnityEngine.Object
    {
        //
        // 摘要:
        //     TODO.
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("The GameObjectRecorder constructor now takes a root GameObject", true)]
        public GameObjectRecorder();
        //
        // 摘要:
        //     Create a new GameObjectRecorder.
        //
        // 参数:
        //   root:
        //     The root GameObject for the animated hierarchy.
        public GameObjectRecorder(GameObject root);

        //
        // 摘要:
        //     The GameObject root of the animated hierarchy. (Read Only)
        public GameObject root { get; }
        //
        // 摘要:
        //     Returns the current time of the recording. (Read Only)
        public float currentTime { get; }
        //
        // 摘要:
        //     Returns true when the recorder is recording. (Read Only)
        public bool isRecording { get; }

        //
        // 摘要:
        //     Binds a GameObject's property as defined by EditorCurveBinding.
        //
        // 参数:
        //   binding:
        //     The binding definition.
        public void Bind(EditorCurveBinding binding);
        //
        // 摘要:
        //     Adds bindings for all of target's properties, and also for all the target's children
        //     if recursive is true.
        //
        // 参数:
        //   target:
        //     .root or any of its children.
        //
        //   recursive:
        //     Binds also all the target's children properties when set to true.
        public void BindAll(GameObject target, bool recursive);
        //
        // 摘要:
        //     Adds bindings for all the properties of component.
        //
        // 参数:
        //   component:
        //     The component to bind.
        public void BindComponent([NotNull] UnityEngine.Component component);
        //
        // 摘要:
        //     TODO.
        //
        // 参数:
        //   target:
        //
        //   componentType:
        //
        //   recursive:
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("BindComponent() using a System::Type is obsolete, use BindComponentsOfType() instead (UnityUpgradable) -> BindComponentsOfType(*)", true)]
        public void BindComponent(GameObject target, Type componentType, bool recursive);
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Obsolete("\"BindComponent<T>() where T : Component\" is obsolete, use BindComponentsOfType<T>() instead (UnityUpgradable) -> BindComponentsOfType<T>(*)", true)]
        public void BindComponent<T>(GameObject target, bool recursive) where T : UnityEngine.Component;
        //
        // 摘要:
        //     Adds bindings for all the properties of the first component of type T found in
        //     target, and also for all the target's children if recursive is true.
        //
        // 参数:
        //   target:
        //     .root or any of its children.
        //
        //   recursive:
        //     Binds also the target's children transform properties when set to true.
        //
        //   componentType:
        //     Type of the component.
        public void BindComponentsOfType(GameObject target, Type componentType, bool recursive);
        public void BindComponentsOfType<T>(GameObject target, bool recursive) where T : UnityEngine.Component;
        //
        // 摘要:
        //     Returns an array of all the bindings added to the recorder.
        //
        // 返回结果:
        //     Array of bindings.
        public EditorCurveBinding[] GetBindings();
        //
        // 摘要:
        //     Reset the recording.
        public void ResetRecording();
        //
        // 摘要:
        //     Saves recorded animation to a destination clip.
        //
        // 参数:
        //   clip:
        //     The destination clip. If this clip has animation curves, they will be removed.
        //
        //   fps:
        //     The frames per second (FPS) for the clip. If no value is specified, by default,
        //     this method uses 60 FPS.
        //
        //   filterOptions:
        //     The filtering options for processing the animation curves when saved to the destination
        //     clip. If no options are specified, by default, this method filters out irrelevant
        //     keys by applying a light compression of 0.5 for positionError, rotationError,
        //     scaleError and floatError.
        public void SaveToClip(AnimationClip clip, float fps);
        //
        // 摘要:
        //     Saves recorded animation to a destination clip.
        //
        // 参数:
        //   clip:
        //     The destination clip. If this clip has animation curves, they will be removed.
        //
        //   fps:
        //     The frames per second (FPS) for the clip. If no value is specified, by default,
        //     this method uses 60 FPS.
        //
        //   filterOptions:
        //     The filtering options for processing the animation curves when saved to the destination
        //     clip. If no options are specified, by default, this method filters out irrelevant
        //     keys by applying a light compression of 0.5 for positionError, rotationError,
        //     scaleError and floatError.
        public void SaveToClip(AnimationClip clip, float fps, CurveFilterOptions filterOptions);
        //
        // 摘要:
        //     Saves recorded animation to a destination clip.
        //
        // 参数:
        //   clip:
        //     The destination clip. If this clip has animation curves, they will be removed.
        //
        //   fps:
        //     The frames per second (FPS) for the clip. If no value is specified, by default,
        //     this method uses 60 FPS.
        //
        //   filterOptions:
        //     The filtering options for processing the animation curves when saved to the destination
        //     clip. If no options are specified, by default, this method filters out irrelevant
        //     keys by applying a light compression of 0.5 for positionError, rotationError,
        //     scaleError and floatError.
        public void SaveToClip(AnimationClip clip);
        //
        // 摘要:
        //     Forwards the animation by dt seconds, then record the values of the added bindings.
        //
        // 参数:
        //   dt:
        //     Delta time.
        public void TakeSnapshot(float dt);
    }
}

首先其存在与UnityEditor.Animations库中;UnityEditor表示该功能只能在编辑器下使用;Animations就是用于录制动画Animations。对于类中的接口,结合下面的示例记录。

示例代码

using UnityEditor.Animations;
using UnityEngine;

public class FaceRecorder : MonoBehaviour
{
    private SkinnedMeshRenderer[] skinnedMeshRenderers;
    public AnimationClip m_clip;
    private GameObjectRecorder m_recorder;

    void Start()
    {
        m_recorder = new GameObjectRecorder(gameObject);
        skinnedMeshRenderers = GetComponentsInChildren<SkinnedMeshRenderer>();
        for (int i = 0; i < skinnedMeshRenderers.Length; i++)
        {
            m_recorder.BindComponent(skinnedMeshRenderers[i]);
        }
    }

    private void LateUpdate()
    {
        if (null == m_clip) return;
        m_recorder.TakeSnapshot(Time.deltaTime);
    }

    private void OnDisable()
    {
        if (null == m_clip) return;
        if (m_recorder.isRecording) m_recorder.SaveToClip(m_clip);
    }
}

解析

首先,需要在项目中创建一个Animation,用于储存我们记录的动画数据;与其对应的便是代码中的AnimationClip对象m_clip,我们需要在Inspector界面对其进行拖拽设置。
创建Animation
之后代码在开启运行并创建完GameObjectRecorder类相应的对象(m_recorder)后,需要将场景中需要跟踪记录的对象组件设置到GameObjectRecorder类的对象中:m_recorder.BindComponent,示例中我使用的是SkinnedMeshRenderer组件,除此之外Transform组件肯定也可以,其余组件以及自己创建的Mono类需要进一步尝试,当然接口中Bind相关的接口有很多,可自行测试。
再之后就是开始进行录制m_recorder.TakeSnapshot。然后就是将录制的数据存储在动画中m_recorder.SaveToClip(m_clip);
检验成果:同视频中的方法一样;保存成功的动画Animation,就可以像平常的Animation一样,使用动画状态机Animator在对应的物体上播放动画即可。

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

Unity中的GameObjectRecorder类录制动画 的相关文章

  • UnityLuaMvvM Lua 带通知的Mode类

    实现数据更新UI自动刷新的核心代码 欢迎关注https gitee com xiongks UnityMVVM mode function modeType local obj obj modeType modeType obj filds
  • Unity单元测试流程

    文章目录 环境 流程 1 创建一个存放 单元测试程序集 的目录 2 打开 Test Runner 窗口 3 选择单元测试模式 4 创建单元测试程序集 5 创建测试脚本 6 运行测试 环境 Unity 2020 3 3f1 流程 1 创建一个
  • unity网络资源导入

    1 找到需要导入的文件 这里导入fbx格式 2 打开unity界面 在Asset目录下创建文件夹FBX 将需要导入的fbx预制体或整个文件夹拖入创建的FBX文件夹下 3 选中需要的fbx预制体并拖至场景中 4 双击定位到当前物体 5 找到需
  • 1.17 从0开始学习Unity游戏开发--场景切换

    前面的所有文章我们都在一个固定的游戏场景内进行开发 在最开始介绍场景这个概念的时候就已经提及 这个场景可以是一张地图 或者是一个对战房间等等 所以显然这个场景可以有多个 并且可以从一个场景切换到另外一个场景 那么在Unity中如何进行场景切
  • Unity 粒子特效、材质发光 HDR ShaderGraph图文教程[完成lit发光设置]

    效果如图 准备工作 在hdr模式下 关闭Directional Light 相机设置 移动球挂一个点光源作为子节点 设置自行调节 0 创建移动球的材质及shader shader gt 在Project Create Shader Grap
  • FBX导入Unity中模型没有材质的处理

    一 3dMax导出FBX时的注意事项 导出时 确保maps文件存在 里面放着fbx用到的image 二 在Unity中的设置 1 文件拖入Unity的Assets文件夹中 2 查看模型的材质是否存在 如下所示 材质为None 此时拖入sce
  • Unity动画控制器animator.CrossFade

    需要特别注意 1 CrossFade虽然可以不用任何逻辑来链接而直接跳转 但是CrossFade只能覆盖其他动画 当当前动画播放完毕而没有跳出这个动画时再次调用CrossFade将会失败 造成动画依旧停在原位 参数animator Cros
  • UnityVR--组件3--Line Renderer--线性渲染

    目录 线性渲染组件简介 绘制线条Line Renderer组件介绍 绘制拖尾Trail Renderer组件介绍 应用1 使用Line Renderer绘制线段 应用1实现 使用系统工具或自定义工具绘制线段 应用2 Trail Render
  • unity中创建询问弹出窗口

    在开发过程中进程会遇到需要弹出一个窗口询问用户是否进行的操作 今天就来制作一个这样弹出窗口 然后根据弹出窗口的选择内容不同进行不同的操作 本例中主要是为了删除一个数据 而在删除数据操作前需要得到用户的一个确认操作 这里面主要用到了Notif
  • unity工程崩溃资源找回

    1 Unity死机未保存场景 当你在Unity中编辑场景 突然死机时 可以在项目文件目录中找到Temp文件夹 双击文件夹 找到 Backupscenes文件夹 把后缀为 backup的文件后缀改为 unity 然后拖进Unity的Proje
  • unity3d大型互动照片墙

    1 本次应客户需求 制作一个大型照片墙互动 输出分辨率为9600 4320 注 unity3d官方推荐最大分辨率为8192 3686 4 经过现场长达24小时暴力测试中途未发生问题 姑且判定可以达到正常标准 废话不多说 先上效果 unity
  • 【Unity】按Esc进入操作菜单

    本文章是基于如下视频的自我总结 https www youtube com watch v JivuXdrIHK0 步骤如下 1 在Canvas 界面添加一个Panel Panel中添加一个按钮 调整按钮的大小为合适大小 调整字体的大小为合
  • unity实现鼠标右键控制视角

    主要实现的功能是相机跟随主角 鼠标右击移动后 相机的视角会旋转 思路 在主角里创建空的子物体 把相机绑在空物体上 通过旋转空物体来实现视角的旋转 要把相机调整到适当位置 代码如下 public float rotateSpeed 100 设
  • unity dots jobSystem 记录

    Looking for a way to get started writing safe multithreaded code Learn the principles behind our Job System and how it w
  • Unity中URP下的指数雾

    文章目录 前言 一 指数雾 雾效因子 1 FOG EXP 2 FOG EXP2 二 MixFog 1 ComputeFogIntensity 雾效强度计算 2 lerp fogColor fragColor fogIntensity 雾效颜
  • 游戏开发常见操作梳理之NPC任务系统

    多数游戏存在任务系统 接下来介绍通过NPC触发任务的游戏制作代码 using System Collections using System Collections Generic using UnityEngine
  • 游戏开发创建操作之玩家信息系统的建立

    游戏一般都需要玩家信息系统 那么我们应该如何搭建玩家信息系统 接下来我将展示一种简单的方法 完整代码如下 using System Collections using System Collections Generic using Uni
  • 游戏开发常见操作梳理系列之——玩家信息的显示系统

    在游戏中 有不少游戏在左上角会出现玩家的头像和等级以及血量 这就是玩家的信息显示系统 那么这些是如何制作的呢 接下来我将讲讲代码的操作 其它操作我会在其它笔记中一一说明 敬请期待 信息的显示相当简单就是控制一些UI 然后在其它系统里面填写相
  • 游戏开发常见操作梳理之NPC药品商店系统(NGUI版)

    后续会出UGUI Json的版本 敬请期待 游戏开发中经常会出现药品商店 实际操作与武器商店类似 甚至根据实际情况可以简化设置 废话不多说 直接上代码 药品商店的源码 using System Collections using Syste
  • 游戏开发中常见系统梳理之背包系统的实现一

    游戏中几乎都存在大大小小的背包系统 接下来我将讲述背包系统具体是如何实现的 完整源码 以下是使用unity NGUI实现 使用txt配置的方法 后续更新UGUI Json实现的背包系统敬请期待 背包中的物品我们常常将其制作成预设体 通过改变

随机推荐

  • 【笔记】构造函数的私有、公有、特权、静态成员

    根据书 javascript DOM高级程序设计 一书整理的笔记 var Myconstuctor function name 特权成员 与私有方法不同 特权方法能够被公开访问 而且还能够访问私有成员 特权方法是指在构造函数的作用域中使用t
  • 玩转wsl2之环境搭建

    Windows是市场占有率最高的桌面操作系统 很多开发人员还是习惯于在Windows系统中进行开发工作 但服务器领域多采用Linux操作系统 因此开发人员在开发过程中 经常会遇到windows系统开发的软件难以部署到Linux系统的问题 W
  • HTML表格嵌套、合并表格

    一 表格元素 lt table gt table常用属性 border 边框像素 width height 表格宽度 高度 bordercolor 表格边框颜色 bgcolor 表格背景颜色 二 tr th td元素 th和td元素是在tr
  • linux学习笔记-安装配置使用clamav杀毒软件

    1 安装clamav 2 更新病毒库 freshclam 如果更新不了 或者更新特别慢 可以手动下载病毒库文件 放到 var lib clamav 文件下 在更新病毒库 病毒库文件链接 三个文件 bytecode cvd http data
  • Python面试题,通过代码获取nginx.log中状态码的出现次数

    先用pyton分析nginx的一行日志 通过split函数把日志变成一个用空格分开的列表 得到了状态码是在索引为8的列表元素 开始操作 打开nginx日志文件 定义一个空字典 用来存放状态码出现的次数 结合while循环遍历每行日志
  • Python面试,这16个问题你一定要熟知

    一 Python 是如何进行内存管理的 答 从三个方面来说 一对象的引用计数机制 二垃圾回收机制 三内存池机制 对象的引用计数机制 Python 内部使用引用计数 来保持追踪内存中的对象 所有对象都有引用计数 引用计数增加的情况 一个对象分
  • C++查看变量类型办法(typeinfo)

    一 类型含意 bool b char c signed char a unsigned char h signed short int s unsigned short int t signed int i unsigned int j s
  • 一文讲懂C#、ASP.NET、ASP.NET MVC、ASP.NET web form、asp.net core mvc的区别

    微软的命名很糟糕 技术上有两个框架 ASP NET和ASP NET Core 它们分别基于 NET Framework和 NET Core构建 当Microsoft首次尝试创建一个遵循MVC模式的 现代 Web应用程序平台时 它将这个新平台
  • 主合取/析取范式

    前置知识 简单合取 析取式 合取 析取范式 极小项 当存在n个命题变项做合取时 如果这个简单合取式出现了全部的命题变项或它的否定形式 且恰好只出现一次 则这个式子属于极小项 以n 3 命题变项为p q r为例 他们的极小项如表 主析取范式
  • Ubuntu16升级为18

    https blog csdn net sean 8180 article details 81075659
  • 从mimikatz抓取密码学习攻防

    前不久在使用mimikatz抓取hash的时候遇到了报错 本着追根溯源的原则去查看了mimikatz抓取密码的原理 在学习的过程中发现了mimikatz的每种报错都有不同的原因 本文就从mimikatz的防御角度出发来分析如何防御mimik
  • 【ubuntu】报错su:认证失败

    问题 ubuntu使用su命令时提示认证失败 解决方法 报这个错误的原因是root用户默认锁定的 只要使用passwd命令重新设置下root密码即可 详细步骤 1 命令行输入sudo passwd 2 根据提示修改密码 3 输入su 4 输
  • Altium Designer编辑PCB时,器件跑出可视界面外的解决方法

    很多人在使用AD等进行PCB设计的时候 由于制作封装问题或者是其他操作问题 会遇到在PCB界面下某一个或者几个封装超出软件显示范围 不论如何移动和放大缩小 都无法显示出来 也就没法选中和编辑 下面就讲讲如何解决这个问题 一个封装超出界外 不
  • Feign 使用 @SpringQueryMap 来解决多参数传递问题

    本文目录 1 Feign传递一个bean对象参数 2 Feign传递一个bean对象参数 多个基本类型参数 3 Feign传递多个基本类型参数 4 Feign传递多个bean对象参数 在实际项目开发过程中 我们使用 Feign 实现了服务与
  • css_流光按钮(转载)

    CSS部分 初始化 取消页面的内外边距 padding 0 margin 0 body 弹性布局 让页面元素垂直 水平居中 display flex justify content center align items center 让页面
  • Mock框架应用(三)-Mock Post请求

    不带参数的post请求 description 不含参数的post请求 request uri post method post response text 不含参数的post请求 带参数的post请求 配置Json 并启动moco服务 d
  • python列表index找不到索引_Python list.index在找不到索引时抛出异常

    Why does list index throw an exception instead of using an arbitrary value for example 1 What s the idea behind this To
  • R语言数据清洗与规整-回归模型为例

    数据清洗和规整是进行数据分析的前提条件 数据的清洗和规整通常会花费比进行数据分析更多的时间 正所谓 清洗一小时 分析五秒钟 数据清洗和规整要依据实际数据的特征进行 其包括缺失值和冗余值的处理 数据重归类 字符类型转换等 这里将使用 狗熊会
  • Opencv C++ 基本数据结构 Mat

    Opencv C 基本数据结构 Mat Mat 构造单通道Mat对象 获取单通道Mat的基本信息 以三行两列的矩阵为例 1 获取行数和列数 2 使用成员函数size 获取矩阵的尺寸 3 使用成员函数channels 获取矩阵的通道数 4 使
  • Unity中的GameObjectRecorder类录制动画

    Unity中的GameObjectRecorder类录制动画 记录 GameObjectRecorder 示例代码 解析 记录 首先是 参考及示例视频 Unity制作战神等级的表情动画 游戏 CG Vtuber适用 相关代码在8分16秒之后