原文
Unity launched Timeline along with Unity 2017.1 and since then, we have received a lot of feedback about it.
Unity的Timeline功能是隨著 Unity 2017.1 一起發(fā)布的, 并且直到現(xiàn)在抡谐,我們收到大量關(guān)于它的反饋裁奇。After talking with many developers and responding to users on the forums,
在論壇上與很多開發(fā)者進(jìn)行交流后,we realized how many of you want to use Timeline for more than as a simple sequencing tool.
我們認(rèn)識(shí)到你們想使用Timeline完成比簡(jiǎn)單的序列化工具 更多的功能I have already delivered a couple of talks about this (for instance, at [Unite Austin 2017]>(https://www.youtube.com/watch?v=nn3SnfNNEmk)) and wrote a blog post on how to use Timeline for non-conventional uses.
我已經(jīng)遞上幾個(gè)關(guān)于講這方面的話題(例如,在 Unite Austin 2017)與寫的一篇博客上面講了 關(guān)于Timeline 的非傳統(tǒng)使用方式Read this blog post to find out about how Timeline can drive dialogues, support branching, or even connect with the AI systems of your game.
閱讀這篇博客去找出如何使用Timeline驅(qū)動(dòng)對(duì)話框, 支持分支, 甚至在你的游戲里關(guān)聯(lián)AI系統(tǒng).
Timeline was designed with extensibility as a main goal from the beginning;
一開始Tlimeline就是把可拓展性作為一個(gè)主要的目標(biāo)麦撵。
the team which designed the feature always had in mind that users would want to create their own clips and tracks in addition to the built-in ones.
設(shè)計(jì)這個(gè)功能的團(tuán)隊(duì)一直會(huì)記在心上的事就是 用戶會(huì)想創(chuàng)建它們自己的clips與tracks 整合到內(nèi)置的功能這些功能中去刽肠。
As such, there are a lot of questions about scripting with Timeline. The system on which Timeline is built upon is powerful, but it can be difficult to work with for the non-initiated.
同樣的溃肪,還有很多與Timeline相關(guān)的腳本問題隙笆。這是一個(gè)強(qiáng)大的系統(tǒng)嘹黔,但是開始會(huì)比較難匆篓。
But first, what’s Timeline? It is a linear editing tool to sequence different elements: animation clips, music,
首先, 什么是Timeline? 它是一個(gè)線性編輯工具能編輯順序排列的不用元素:動(dòng)畫片段, 音樂,
sound effects, camera shots, particle effects, and even other Timelines. In essence, it is very similar to tools
音效, 攝像機(jī), 特效, 甚至其他Timeline. 本質(zhì)上, 它非常像一些工具
such as Premiere?, After Effects?, or Final Cut?, with the difference that it is engineered for real-time
playback.
比如: Premiere?After Effects?, or Final Cut?(譯者注:視頻編輯工具) 區(qū)別在于這是為實(shí)時(shí)回放設(shè)計(jì)的.
For a more in-depth look at the basics of Timeline, I advise you to visit the Timeline documentation section of the Unity Manual, since I will make extensive use of those concepts.
要Timeline更細(xì)節(jié)的內(nèi)容. 我建議你訪問Unity手冊(cè)中的Timeline文檔, 因?yàn)槲覍?huì)更廣泛的使用這些概念眶拉。
The Playable API
Timeline is implemented on top of the Playables API.
Timeline 的實(shí)現(xiàn)是基于Playables API
It is a set of powerful APIs that allows you to read and mix multiple data sources (animation, audio and more) and play them through an output.
這是一套強(qiáng)大的APIs甜橱, 允許你讀取并混合多個(gè)數(shù)據(jù)源(動(dòng)畫, 聲音更多) 并通過一個(gè)輸出播放他們幔欧。
This system offers precise programmatic control, it has a low overhead and is tuned for performance.
Incidentally, it’s the same framework behind the state machine that drives the Animator Component, and if you have programmed for the Animator you will probably see some familiar concepts.
這套系統(tǒng)提供精確的可編程控制, 它擁有低開銷并且是在性能上經(jīng)過優(yōu)化的匙铡。
順帶一提, 它是與state machine背后驅(qū)動(dòng)Animator組件的框架用的是同一套, 如果你已經(jīng)為Animator編寫過程序你
或許會(huì)看到相似的概念撵摆。
Basically, when a Timeline begins playing, a graph is built composed of nodes called Playables. They are organised in a tree-like structure called the PlayableGraph.
基本上, 當(dāng)一個(gè)Timeline開始播放, 一個(gè)由節(jié)點(diǎn)組成的圖稱為Playables. 它們組織成的一個(gè)樹狀結(jié)構(gòu)叫 PlayableGraph.
Note: If you want to visualise the tree of any PlayableGraph in the scene (Animators, Timelines, etc.) you can download a tool called PlayableGraph Visualizer. This post uses it to visualize the graphs for the different custom clips. To know more about the Playable API and the graph (in relationship to the Animator), you can check Pierre-Paul’s blog post.
注意: 如果你想在場(chǎng)景中顯示任何PlayableGraph的樹狀圖(Animators, Timelines, etc.)你可以下載一個(gè)工具叫 PlayableGraph Visualizer.
這篇文章就是使用它去顯示不同的自定義clips的圖表. 要知道更多關(guān)于Playable API 和 這圖表诞挨, 你可以訪問
Pierre-Paul’s blog post.
I will now go through three simple examples that will show you how to extend Timeline.
我現(xiàn)在將通過3個(gè)范例給你展示如何拓展Timeline.
In order to lay the groundwork, I will begin with the easiest way to add a script in Timeline. Then, more concepts will be added gradually to make use of most of the functionalities.
為了先打下一個(gè)基礎(chǔ), 我將會(huì)從最簡(jiǎn)單的方式在Timeline中添加一個(gè)腳本. 然后, 更多的概念將會(huì)逐步的添加進(jìn)來 最終產(chǎn)生一個(gè)大多數(shù)情況都能使用的版本.
Assets
I have packaged a small demo project with all of the examples used in this post.
我有個(gè)包 a small demo project 包含了這篇博客上所有的例子莉撇。
Feel free to download it to follow along. Otherwise, you can enjoy the post on its own.
免費(fèi)下載這個(gè)例子感受一下』躺担或者棍郎,你可以自己愉快的閱讀這篇博客。
Note: For the assets, I have used prefixes to differentiate the classes in each example (“Simple_”, “Track_”, “Mixer_”, etc.). In the code below, these prefixes are omitted for the sake of readability.
注意:對(duì)于assets, 我使用了一些前綴去區(qū)分每個(gè)例子的類名(“Simple_”, “Track_”, “Mixer_”, 等.).
在下面的代碼里, 為了可讀性這些前綴被已經(jīng)被省略了.
Example 1 – Custom clips
范例 1 自定義clips
This first example is very simple: the goal is to change the color and intensity of a Light component with a custom clip. To create a custom clip, you need two scripts:
這第一個(gè)范例是非常簡(jiǎn)單的: 目標(biāo)是用一個(gè)自定義的clip改變Light組件的顏色與強(qiáng)度.
要?jiǎng)?chuàng)建一個(gè)自定義clip, 你需要兩個(gè)腳本:
One for the data: inheriting from PlayableAsset
一個(gè)用于數(shù)據(jù):繼承自PlayableAsset
One for the logic: inheriting from PlayableBehaviour
一個(gè)用于邏輯:繼承自PlayableBehaviour
A core tenet of the Playable API is the separation of logic and data. This is why you will need to first create a PlayableBehaviour, in which you will write what you want to do, like so:
1個(gè)核心的原則是Playable API邏輯與數(shù)據(jù)是分離的. 這就是為什么當(dāng)你想做任何事情之前, 你將需要先創(chuàng)建一個(gè)PlayableBehaviour银室,比如這樣:
'''
public class LightControlBehaviour : PlayableBehaviour
{
}
'''
public class LightControlBehaviour : PlayableBehaviour
{
public Light light = null;
public Color color = Color.white;
public float intensity = 1f;
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
if (light != null)
{
light.color = color;
light.intensity = intensity;
}
}
}
'''