Unity Timeline 扩展

这里认为大家已经会timeline的基本使用了,只介绍怎么自定义扩展。

第一步.自定义Track

首先要自定义一条轨道。剪辑是要在轨道里跑的,系统自带的轨道我们加不了自定义剪辑,得新建自己用的。这个很简单。

[TrackClipType(typeof(TransformTweenClip))] //关联的Clip类型
[TrackBindingType(typeof(GameObject))] //绑定的数据类型。
public class TestTrack1 : TrackAsset
{
}

编译过后就可以在Timeline的窗口里创建这个轨道了。后面再给这个轨道关联我们的自定义剪辑。

主要就是几个属性的作用需要了解一下。

[TrackClipType(type))]
指定关联的Clip类型,如果一个都没有,在Track上右键菜单里就没有可创建的clip。

[TrackBindingType(type))]
指定绑定的数据类型。这样在Track上会出现对象选择器,绑定的数据对象会作为playdata参数传递给我们(后面会看到)。

 

此外还有

[TrackColor(0,255,0)]轨道颜色 是0~255的值

第二步 创建Clip数据

Timeline窗口里编辑的是数据,这个就是定义Clip的数据。数据和逻辑分离的设计,很好理解。

public class TestClip1 : PlayableAsset
{public Transform trans;public Vector3 start;public Vector3 end;
}

记得用[TrackClipType(typeof(TestClip1))] 把它在TestTrack1上关联。

第三步 创建Clip的行为

public class TestClip1Behaviour : PlayableBehaviour
{public TestClip1 data;public override void ProcessFrame(Playable playable, FrameData info, object playerData){base.ProcessFrame(playable, info, playerData);data.trans.localScale = Vector3.Lerp(data.start, data.end, (float)(playable.GetTime() / playable.GetDuration()));//Clip上的当前时间/总时间}
}

还需要让数据和逻辑关联起来,Unity不知道TestClip1对应的是TestClip1Behaviour。Unity采取的办法是让我们在数据里的一个虚函数里创建逻辑对象并返回。TestClip1需要加一点代码。

public class TestClip1 : PlayableAsset
{public Transform trans;public Vector3 start;public Vector3 end;//增加的代码如下:public override Playable CreatePlayable(PlayableGraph graph, GameObject owner){return ScriptPlayable<TestClip1Behaviour>.Create(graph, new TestClip1Behaviour(){data = this});}
}

也很简单。

剪辑的行为对象在这个ScriptPlayable<T>里面,如果我们要获取其他剪辑行为对象,首先获取到的也是这个东西。通过T ScriptPlayable<T>.GetBehaviour()就可以获取到具体的行为对象了。这个后面做剪辑混合会用到。具体可以看手册。

编译结束后就可以去Timeline窗口里创建剪辑了。

小结

基本的剪辑扩展就完成了,功能都在Behaviour里。

一般会将控制的场景对象作为数据绑定传递到Clip和Mixer,作为字段放在Clip里会有引用丢失问题。

进阶一 ExposedReference<T>

需要注意的是,上面为了省事,TestClip1里直接把Transform声明为变量了。但是Timeline存储后是一种资源,资源是不能直接引用场景里的东西的,也就是说trans字段的引用对象不会保存到对象。这里可以通过关闭场景然后再次打开来验证,Timeline文件上引用的场景对象会丢失。

为了解决这个问题,unity搞了个ExposedReference<T>类型来实现对场景里的东西引用。估计是用路径查找实现的,具体就没去翻了。只需要将定义改成这样就行了:

public ExposedReference<Transform> trans;//获取真正trans对象的代码为:
//trans.Resolve(playable.GetGraph().GetResolver())

详情可以看这里:

【Unity学习笔记】ExposedReference类的初识 + 自定义Timeline轨道初识-CSDN博客

进阶二 剪辑混合

剪辑混合是一条Track里的多个剪辑发生过渡时,根据各个剪辑的权重用户自己算出一个最终的值。这个过程Unity不会自动做,要撸代码。注意混合是Track层面的事情,不是Clip里的事,要遍历多个Clip来计算。

总共可分两步。第一步创建混合行为代码。

public class TestTrack1Mixer : PlayableBehaviour
{public override void ProcessFrame(Playable playable, FrameData info, object playerData){base.ProcessFrame(playable, info, playerData);var inputCount = playable.GetInputCount();var scale = Vector3.zero;for(int i = 0; i < inputCount; i++){var scriptPlayable = (ScriptPlayable<TestClip1Behaviour>)playable.GetInput(i);var bhv = scriptPlayable.GetBehaviour();//如果不是TestClip1Behaviour,这里会返回null。设计时注意即可。float weight = playable.GetInputWeight(i);//Behaviour是在包含它的ScriptPlayable<T>里跑的,时间从scriptPlayable这个变量获取,而不是函数传入的playable变量scale += weight * Vector3.Lerp(bhv.data.start, bhv.data.end, (float)(scriptPlayable.GetTime() / scriptPlayable.GetDuration()));}//这里用了playerData,就是[TrackBindingType(typeof(GameObject))] 绑的var go = playerData as GameObject;go.transform.localScale = scale;}
}

这里混合后最后控制的对象是playerData传入的。从遍历到的TestClip1Behaviour上取也行,但是不如这样方便。

第二步在Track1Asset里创建这个混合器。

[TrackClipType(typeof(TransformTweenClip))] //关联的Clip类型,如果一个都没有,在Track上右键菜单里就没有可创建的clip。
[TrackBindingType(typeof(GameObject))] //绑定的数据类型。
public class TestTrack1 : TrackAsset
{//新增的代码public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount){return ScriptPlayable<TestTrack1Mixer>.Create(graph, inputCount);}
}

进阶三 自定义信号

继承自SignalEmitter就行了。

public class TestSignal : SignalEmitter
{public string arg;
}

编译通过后,Timeline编辑器里就会显示自己的信号。

既然已经自定义信号了,那么也得自定义一个信号接收器了,自带的信号接收器SignalReceiver不能处理自定义信号。代码如下,也很简单。

public class TestSignalReceiver : MonoBehaviour, INotificationReceiver
{public void OnNotify(Playable origin, INotification notification, object context){var s = notification as TestSignal;Debug.Log(s.arg);}
}

系统自带的信号发送和接收,相当于就是把一个资源文件作为信号参数传递,然后根据信号参数调用对应处理函数,大多数情况下用系统自带的就够用了。

参考

Timeline:实用指南

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/33359.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文生图技术的演进、挑战与未来:一场重构人类创造力的革命

摘要 文生图&#xff08;Text-to-Image Generation&#xff09;技术作为生成式人工智能&#xff08;Generative AI&#xff09;的核心分支&#xff0c;正在以颠覆性力量重塑内容生产范式。本文系统梳理文生图技术从早期实验到多模态大模型的演进路径&#xff0c;分析其在设计、…

如何手动使用下载并且运行 QwQ-32B-GGUF

首先使用安装 pip install ModelScope 使用 ModelScope 下载对应的模型 modelScope download --model Qwen/QwQ-32B-GGUF qwq-32b-q4_k_m.gguf 第二步开始下载 ollama git clone https://githubfast.com/ggerganov/llama.cpp # githubfast.com 可以加速下载 切换到目录&am…

SPring 学习积累1 关于下载相关jdk maven 版本

3.15.1 注意下载的版本 有些是不适配的&#xff0c;官网有提示&#xff1b; 3.15.2 注意配置环境变量时需要注意admistartor 中的java路径和系统变量是否一致&#xff0c;一行要一致&#xff0c;不然后续安装maven之后&#xff0c;使用命令 mvn -version时会显示以下错误&…

Excel(函数篇):Vlookup函数 详细用法

目录 Vlookup函数基础用法精确查找易错问题员工信息查询表 进阶用法近似匹配&#xff08;模糊查找&#xff09;结合通配符查找反向查找 高级技巧多条件查找动态列查询 错误处理屏蔽错误值处理数字/文本格式问题注意事项常见错误解决方案 拓展用法跨表与跨工作簿查找查找返回多列…

对最近的刷题做一个小总结(关于动态规划和贪心)

文章目录 1. 小总结2. 两道算法题2.1 数组中两个字符串的最小距离2.2 孩子们的游戏 1. 小总结 最近刷了很多算法题&#xff0c;真正了解到的算法应是dfs&#xff0c;多元dfs&#xff0c;以及动态规划和贪心。 dfs和多元dfs目前并没有真正深入研究过&#xff0c;不过熟悉套路之…

jmeter分布式原理及实例

一、执行原理 二、相关注意事项 关闭防火墙所有上网控制机、代理机、服务器都在同一个网络上所有机器的jmeter和java版本必须一致关闭RMI.SSL开关 三、配置和执行 配置&#xff1a; 修改bin/jmeter.properties文件&#xff1a; 代理机&#xff1a; 修改服务端口&#xff1…

C++ STL 详解 ——vector 的深度解析与实践指南

一、vector 的核心概念与底层机制 1.1 动态数组的本质 连续内存存储&#xff1a;与普通数组相同&#xff0c;vector 使用连续的内存空间&#xff0c;支持 O (1) 时间复杂度的随机访问。动态扩容特性&#xff1a;通过push_back等操作自动调整容量&#xff0c;无需手动管理内存…

【SpringBoot】——在做一些项目中所学到的新的技术栈和一些小技巧(主要为MQ,详细请看目录和文章)

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大三学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

0经验cursor开发一款跨端app

设备&#xff1a;mac电脑cursor 1.输入诉求 我要实现一个跨端的地址应用&#xff0c;使其可以在ios、安卓、小程序和网页端都可以使用。这是一个demo的项目&#xff0c;功能不必要太过复杂&#xff0c;下面需要你和我多次沟通完成这个任务。你先根据我的内容输入&#xff0c…

Element Ui - 编辑时表单校验信息未清空问题处理

Element Ui 关闭对话框清空验证消息&#xff0c;清除form表单的操作 首先在对话框 取消按钮 添加 click事件&#xff0c;例如&#xff1a;&#xff08;ps&#xff1a;callOf 里面的addGroupData和ref - - &#xff09; <div slot"footer" class"dialog-foo…

OpenCV图像加权函数:addWeighted

1 addWeighted函数 在OpenCV 里&#xff0c;addWeighted 函数的作用是对两个图像进行加权求和&#xff0c;常用于图像融合、图像过渡等场景。函数如下&#xff1a; cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])2 参数解释 src1&#xff1a;第一个输入图…

Science Robotics 利用机器学习进行鳐鱼的仿生设计

对于海洋生物而言&#xff0c;生物力学和流体动力学力都会对游泳速度施加物理限制&#xff0c;促使游泳策略和鳍形状的趋同进化。鉴于这些限制是与尺度相关的&#xff0c;如雷诺数&#xff08;Re&#xff09;&#xff0c;这就产生了自然运动缩放定律&#xff0c;该定律根据生物…

基于ssm的一家运动鞋店的产品推广网站的设计

项目简介 一家运动鞋店实现了以下功能&#xff1a; 实现了用户在线选择试题并完成答题&#xff0c;在线查看考核分数。管理员管理收货地址管理、购物车管理、字典管理、留言版管理、新闻信息管理、产品管理、产品收藏管理、产品评价管理、产品订单管理、单页数据管理、用户管…

什么是后训练?大语言模型训练后优化方法综述,87页pdf

大语言模型&#xff08;LLMs&#xff09;的出现彻底改变了自然语言处理领域&#xff0c;使其在从对话系统到科学探索的各个领域中变得不可或缺。然而&#xff0c;其预训练架构在特定场景中往往表现出局限性&#xff0c;包括推理能力受限、伦理不确定性以及领域特定性能欠佳等问…

python开发订单查询功能(flask+orm bee)

1. 搭建python环境。 可以参考其它文档。 此处python使用 3.12 IDE随意&#xff0c;PyCharm 或 Eclipse PyDev也可以。 2. Flask 2.1 安装Flask pip install Flask 2.2 一个最简单的flask实例 创建一个工程&#xff0c; 新建一个 main.py文件&#xff0c; 输入以下内容…

工作记录 2017-01-11

工作记录 2017-01-11 序号 工作 相关人员 1 协助BPO进行Billing的工作。 修改邮件上的问题。 更新RD服务器。 郝 更新的问题 1、修改了Patient Insurance的文件上传。 1.1 文件存储改为MedI“EHRWfs”Account“patientInfo”MRN 1.2 “Upload Files” to “Upload/Vie…

基于javaweb的SpringBoot个人健康管理系统小程序微信小程序设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…

b站视频下载工具软件怎么下载

自行配置FFMPEG环境 请优先选择批量下载&#xff0c;会自处理视频和音频文件。 如果要下载更高质量请登陆。 没有配置FFMPEG下载后会有报错提示&#xff0c;视频音频文件无法合并生成mp4文件 更新批量下载标题&#xff0c;只取视频原标题&#xff0c;B站反爬机制登陆后下载多了…

简单的模拟法

1. 鸡兔同笼问题&#xff0c;鸡有2只脚 &#xff0c;兔有4只脚&#xff0c;已知脚数求最多有几只动物 #include <stdio.h>void feet(int x){if(x%2 0){if(x%4 0) printf("max%d,min%d",x/2,x/4);else printf("max%d,min%d",x/2,(x-2)/41);}else …

【python爬虫】酷狗音乐爬取练习

注意&#xff1a;本次爬取的音乐仅有1分钟试听&#xff0c;仅作学习爬虫的原理&#xff0c;完整音乐需要自行下载客户端。 一、 初步分析 登陆酷狗音乐后随机选取一首歌&#xff0c;在请求里发现一段mp3文件&#xff0c;复制网址&#xff0c;确实是我们需要的url。 复制音频的…