宇宙第一小正太\ (o)/~萌量爆表求带飞=≡Σ((( つo)つ~ dalao们点个关注呗~


三大继承类:

(1)PlayableTrack
(2)PlayableBehavior
(3)PlayableAsset

注:当你覆写其中的函数,如果有base开头的(在使用自动补全代码的时候出现),请删掉。
另外在PlayableAsset的头上加上序列化Attribute: [System.Serializable]

完全理解Timeline:

我们在Timeline里面添加的clip序列,应该由PlayableDirector来管理,通过TrackAsset里面的GetClips函数,可以将里面指定的Track所有的clip获取。
我们可以在外部通过GetComponent来获得PlayableDirector组件,进而来操作整个Timeline的当前播放时间,开始播放,和暂停播放等一系列行为。

消失的TimelineApi:

在新版本的中文API中,并未提供有关Timeline的Api。
这里笔者找到了一个老的API参考,供读者食用:

https://docs.unity3d.com/cn/2017.2/ScriptReference/Timeline.TimelineClip.html
(下图是2017版本API参考手册:)

(下图是2021版本API参考手册:)

在Timeline的API里面提供了如何获取Timeline轨道里面的片段信息,如片段的数量,某个片段的开始时间,片段的结束时间等。

掌握Playable基础:

Playable是Unity实现动画系统的底层逻辑,实际上无论是Animator还是Timeline的实现实际上都使用了它。如果想要使用Timeline结合PlayableScript玩得很溜的话,那么熟练掌握Playable是很有必要的,好在,Playable并不复杂,很好理解和掌握。
这里推荐了一位知乎大佬的博客,通过这篇博客您可以很好的理解Playable的基本原理。
https://zhuanlan.zhihu.com/p/380124248

补充内容:

使用插件来可视化调试Playable,插件名称:PlayableGraph Visualizer,完全免费。可以看到自定义的Timeline的结构。

PlayableTrack:

继承自这个类的C#文件,定义了一个新的Timeline的轨道,当您写下如下代码:

using UnityEngine;
using UnityEngine.Timeline;
[TrackColor(2, 5, 1)]
[TrackBindingType(typeof(MonoBehaviour))]
[TrackClipType(typeof(Asset))]
public class CustomTrack : PlayableTrack {}

您无需将代码挂在一个GameObject上面。直接保存代码,然后就可以在TimeLine添加这条轨道了。[TrackBindingType(typeof(MonoBehaviour))]这个Attribute指定了Track绑定对象的类型。新添加的轨道名称就是CustomTrack。(如果安装上面的写法,您可以自定义你喜欢的名称)在Timeline添加轨道的加号那里,你就能看见这个选项了。

PlayableBehavior:

继承自这个类的C#文件则是定义了Playable的行为。
在这里,我们编写逻辑,比如覆写OnBehaviourPlay函数来记录Timeline第一次进入这个Behavior的时间,以此来计算(预测)结束的时间,通过Duration来获得clip持续的时间。
比如,我们可以进行一个阻塞的TimelineClip,当运行到结尾的时候又返回到刚刚进入Clip的时刻,直到条件允许,在继续播放Clip,这个技巧在制作GalGame的时候特别有用,特别是当您的Dialog弹出来,但是却没有找到一个高效的结构来管理你的这个Dialog文字顺序的时候,我建议您尝试一下Timeline结合您的程序,或许会给您带来新的思路。
其中Behavior的重点内容是:ProcessFrame(Playable playable, FrameData info, object playerData)函数。可以看见的是,这个函数有三个参数,中间的参数info有一个很重要的float变量是info.weight,这个变量的意思是,混合节点输入的权重(小熊瞎说的),其实就是我们刚刚的在“掌握Playable基础”中的那副图片的Edge Weight,在右下角。混合的权重不同罢了,这也是您在实现混合自定义的时候,可以使用到的变量。
将Asset文件as到轨道绑定的对象:下面这句话是万中的核心:

        Light light = playerData as Light; if (light != null) {light.color = color;light.intensity = intensity;}

通过了as的转换操作,因为playData是object类型,所以可以使用as来转换一下。
对于playable的官方定义是:The user data of the ScriptPlayableOutput that initiated the process pass.小熊看不懂,但是小熊会使用它,嘿嘿嘿,其实小熊也不知道为什么这样,就可以使得绑定在Track的物体进行动态修改,但是事实上还真的就是这样,因为官方给的案例程序我琢磨了一下,人家也是这么写的,如果您知道为什么答案是这样写的,请在评论区或者私信告诉小熊,小熊感激不尽。

PlayableAsset:

继承自这个类的C#文件,是Unity允许您拖拽到Track上面的脚本文件,这个文件的public变量出现在了Inspect中。
当您创建出了这个文件的时候,您一定会发现,Unity会向您报一个错误,那就是未能覆写CreatePlayable函数。
也许到这里您已经完全猜出来了Asset文件的作用,没错。小熊当时也很搞不明白为什么有Behavior和Asset这种繁琐的东西,但是小熊在看到Unity报错的时候,就突然醒悟过来,原来不过就是这么一回事。
当Asset进入轨道的时候,Unity帮我们创建了一个Playable,这个Playable是没有灵魂的,它必须要套上一个Behavior的壳子,才会有了灵魂。(*这里肯定有读者不是我这样想的,诚然,您有别的方法创作灵魂不用Behavior,那先不在我们的讨论范围之内
然后CreatePlayable函数返回了这个有壳子和有灵魂的Playable,这里建议您仔细阅读代码。
至于Asset里面的GetBehavior函数,这个函数让您可以访问刚刚创建的scriptPlayable里面的东西。从而设置一些变量之类的东西。

小熊范例代码灯光控制:

以下所展示的代码,将会在clip末尾的时候,跳回clip开始的时候,因为没有在OnPause的时候跳回,所以这段的OnBehaviourPlay只会执行一次。

using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
public class LightControlBehaviour : PlayableBehaviour {//public Light light = null; 不再需要它了public Color color = Color.white;public float intensity = 1f;public PlayableDirector playableDirector;public TimelineClip clip;double startTime = 0f;double totalTime = 0f;public override void ProcessFrame(Playable playable, FrameData info, object playerData) {Light light = playerData as Light; // 这个地方有变化if (light != null) {light.color = color;light.intensity = intensity;}//使用下面到判断来在pasue自带的暂停之前来停下TimeLineif (playable.GetDuration() - playable.GetTime() < 0.083333f) {//playableDirector.time -= 0.08f;playableDirector.time = startTime;
#if InDebugModeDebug.Log("手动暂停");
#endif}}public override void OnBehaviourPlay(Playable playable, FrameData info) {base.OnBehaviourPlay(playable, info);startTime = playableDirector.time;Debug.Log("开始");}
}

小熊的验证程序:

测试方向:我们想通过Timeline来动态修改Cube上面的这个MonoBehavior的变量的数值。

文件存放位置: 在T1文件夹中存放了CustomTrack.cs和Behaviour.cs和Asset.cs

场景中GameObject:一个Cube挂在了SayHello.cs,一个Timeline的空物体挂在了一个PlayerDirector。Timeline序列创建完成,并且被PlayerDirector控制。

PlayableTrack:

CustomTrack.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Timeline;
using UnityEngine.Playables;
[TrackColor(2, 5, 1)]
[TrackBindingType(typeof(MonoBehaviour))]
[TrackClipType(typeof(Asset))]
public class CustomTrack : PlayableTrack {}

PlayableBehaviour:

Behavior.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
// A behaviour that is attached to a playable
public class Behaviour : PlayableBehaviour {public string Text;public override void ProcessFrame(Playable playable, FrameData info, object playerData) {//通过下面的这句代码,即可在绑定过对象的轨道上进行传递参数的操作。playData就是我们放在轨道上面自定义的Asset。SayHello sayHello = playerData as SayHello;if (sayHello != null) {//对轨道绑定的对象进行值的传递。sayHello.Text = Text;}}
}

PlayableAsset:

Asset.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
[System.Serializable]
public class Asset : PlayableAsset {public string Text;// Factory method that generates a playable based on this assetpublic override Playable CreatePlayable(PlayableGraph graph, GameObject go) {//通过下面的两行代码进行创建一个新的Playable(Script类型),然后通过GetBehavior来访问刚刚创建的var scriptPlayable = ScriptPlayable<Behaviour>.Create(graph);
//上方create实际接受两个参数,第一个参数是graph,第二个参数是我们创建的这个Playable接受几个输入,默认不填写那么就是0个输入。var scriptBehavior = scriptPlayable.GetBehaviour();scriptBehavior.Text = Text;
//返回刚刚创建出来的Playable,Unity会帮助我们自动的连线。return scriptPlayable;}
}

Cube绑定的验证程序:

说明:将此脚本绑定在了一个测试用的Cube上面,实际上,您绑在空物体上面也没有什么问题。
测试方向:我们想通过Timeline来动态修改Cube上面的这个MonoBehavior的变量的数值。

SayHello.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//下面的Attribute是为了方便测试,可以让脚本在EditMode下面运行,而无需点击运行程序。
[ExecuteInEditMode]
public class SayHello : MonoBehaviour {public string Text;public int index;// Start is called before the first frame updatevoid Start() {}// Update is called once per framevoid Update() {// Debug.Log(Text);}
}

Timeline轨道布局参考:

我们在自定义的轨道上面放置了两个Asset。
第一个Asset指定了Text的内容为12313,而第二个Asset指定了Text的内容为520。
我们在自定义轨道上面绑定了我们的Cube(SayHello)脚本。
(最上面的轨道请无视,是笔者进行研究的时候留下的轨道)

结果验证:

(1)当Timeline的时间处于第一个Asset:

注意右侧检查器的SayHello脚本的值已经变为了我们期待的结果。
(2)当Timeline的时间处于第二个Asset:

注意右侧检查器的SayHello脚本的值已经变为了我们期待的结果。这里笔者以自己的节操担保,笔者并没有偷偷去修改答案使得结果符合预期,这里笔者建议读者进行自行的验证。我们同样可以可以注意到SayHello的index(显示为“索引”)并没有进行更改,这是因为我们在Asset里面仅仅只是传入了Text数据,并没有传入index数据和进行对轨道的传递。


铛铛铛,小熊

【Unity游戏开发】TimelinePlayable结合使用,Track自定义Timeline轨道相关推荐

  1. Unity游戏开发大师班

    大小解压后:8.63G 持续时间19h 包含项目文件 1280X720 MP4 语言:英语+中英文字幕(根据原英文字幕机译更准确) Unity游戏开发大师班 信息: 要求 –没有课程要求,展示了开发过 ...

  2. unity 角度限制_喵的Unity游戏开发之路 推球:游戏中的物理

    前言很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此我们精选了一套国外优秀的Unity3D游戏开发教程,翻译整理后放送给大家,教您从零开始一步一步掌握Unity3D游戏开发. 本 ...

  3. 喵的Unity游戏开发之路 - 推球:游戏中的物理

    很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此我们精选了一套国外优秀的Unity3D游戏开发教程,翻译整理后放送给大家,教您从零开始一步一步掌握Unity3D游戏开发. 本文不 ...

  4. 40个Unity游戏开发小阴招

    推荐阅读: 我的CSDN 我的博客园 QQ群:704621321 我的个人博客 Unity游戏开发小技巧集结,不用谢我,我只是大自然的搬运工 1. 借助 Prefab 暂存数据 可以直接在脚本的 In ...

  5. 喵的Unity游戏开发之路 - 游泳

    原文: https://mp.weixin.qq.com/s/-ERFNB1GRZ6UAkHOhP9UQw 很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此我们精选了一套国外优秀 ...

  6. 喵的Unity游戏开发之路 - 在球体上行走

    很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此我们精选了一套国外优秀的Unity3D游戏开发教程,翻译整理后放送给大家,教您从零开始一步一步掌握Unity3D游戏开发. 本文不 ...

  7. 喵的Unity游戏开发之路 - 对象持久化

    原文: https://mp.weixin.qq.com/s/NNLHFLEBJE_UIksBtDcglA 前言         很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此 ...

  8. 喵的Unity游戏开发之路 - 复杂重力

    转载(拷贝)自微信公众号(u3dnotes),图片和视频请查看原文: https://mp.weixin.qq.com/s?__biz=MzUxMDM3MTYwNQ==&mid=2247493 ...

  9. 最全面的Unity游戏开发指南视频教程 第2卷

    最全面的Unity游戏开发指南视频教程 第2卷 流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小 ...

最新文章

  1. ROS学习(七):ROS launch 文件
  2. git stash pop冲突_这有一份 git 日常使用清单,你需要吗?
  3. ASP.NET MVC 5 入门教程 (3) 路由route
  4. Chromium下载各类版本(pyppeteer爬虫)
  5. 一款好看的单页个人引导页源码
  6. FPGA同步复位设计代码
  7. 不完全遍历Csrss进程中的句柄表
  8. Camera IIC总线
  9. ctc系统通信前置服务器,CTC系统包括哪些接口服务器?
  10. linux sftp 重命名,SFTP对文件重命名 删除 退出 查看
  11. 为什么我的服务器没有信号,服务器显示器无信号
  12. 神奇宝贝/数码宝贝分类器笔记-机器学习-李宏毅2021
  13. ncbi-genome-download在NCBI上批量下载基因组
  14. GitHub: ProxyPool 爬虫代理IP池
  15. 论坛报名 | Sanjeev Arora,周志华,马毅,张长水……
  16. 自媒体素材采集平台,素材采集方法都有这些
  17. ZUCC_Linux系统管理_实验四 用户和分组管理
  18. mysql 时间字符串 1_Mysql 中的日期时间字符串查询
  19. 爬取彼岸网所有4K美图壁纸--Python脚本
  20. 我愿称之为最容易上手的编程语言——Yaklang(I)

热门文章

  1. 原生 CSS Custom Highlight 终于来了
  2. 随想录(基层团队管理总结)
  3. 嵌入式本来就很坑,相对于互联网来说那个坑多得简直是难走
  4. 开关电源SW节点振荡,你真的了解吗?
  5. 今天轮到我来撕ConcurrentHashMap了
  6. 2022全国数学建模-C 题复盘 古代玻璃制品的成分分析与鉴别
  7. Java程序设计 图形用户界面 【十三】菜单
  8. [附源码]JSP+ssm计算机毕业设计大学生收书系统j7k68【源码、数据库、LW、部署】
  9. 两条路径分散在树林中:使用JavaScript if ... else语句
  10. p6-day17 作业