Timeline給不同類型的對(duì)象建立不同的軌道,在每個(gè)軌道的時(shí)間線上我們可以組織動(dòng)畫播放、音頻播放,游戲?qū)ο蟮娘@隱等操作,也可以自定義軌道完成一些個(gè)性化操作
使用Timeline需要Playable Director組件,它控制Timeline的播放,暫停,循環(huán)等功能,Timeline可以看作是劇本,Playable Director就是導(dǎo)演
名稱 | 描述 |
---|---|
Playable | 引用Timeline資源 |
Update Method | 控制時(shí)間增加的方式 |
DSP,基于DSP(數(shù)字聲音處理)時(shí)鐘。對(duì)于需要與音頻同步的圖形,使用此選項(xiàng) | |
GameTime,基于Time.time更新,默認(rèn)選項(xiàng) | |
UnscaledGameTime,基于Time.unscaledTime更新,即使游戲暫停,也需要對(duì)圖形進(jìn)行更新 | |
Manual,手動(dòng)更新,使用PlayableGraph.Evaluate接口更新 | |
Play On Awake | 組件喚醒時(shí)是否自動(dòng)播放 |
Wrap Mode | Hold,播放完停在最后一幀,Loop,循環(huán)播放,None,播放完回到第一幀 |
Initial Time | 從片段的第幾秒開始播放 |
Bindings | 軌道上綁定的資源 |
在場景中選中某個(gè)游戲?qū)ο?,Window -> Sequencing -> Timeline 打開Timeline窗口
點(diǎn)擊Create創(chuàng)建Timeline Asset,它存儲(chǔ)軌道及片段相關(guān)信息
也可以右鍵 -> Create -> Timeline,創(chuàng)建Timeline Asset,它以playable結(jié)尾
Timeline上可以創(chuàng)建多種類型的軌道,上方顯示時(shí)間(秒或者幀),通過右上角齒輪切換,F(xiàn)rames是幀,Seconds和Timecode是秒,只是格式不一樣
滾動(dòng)鼠標(biāo)中鍵調(diào)整時(shí)間顯示范圍,按住Ctrl,滾動(dòng)鼠標(biāo)中鍵,調(diào)整軌道寬度
Track Group
Track Group類似一個(gè)文件夾,把一些軌道放在一起形成一個(gè)Group,可以折疊起來,方便管理
Activation Track
這個(gè)軌道控制游戲?qū)ο笫欠窦せ?,一個(gè)軌道只能控制一個(gè)對(duì)象是否激活
把游戲?qū)ο笸系阶髠?cè)的槽位上,這里對(duì)一個(gè)Cube操作,右鍵Add Activation Clip,當(dāng)時(shí)間處于Active片段內(nèi)時(shí)會(huì)激活游戲?qū)ο?,否則隱藏游戲?qū)ο螅c(diǎn)擊軌道左側(cè)(紅框范圍),在Inspector上顯示軌道相關(guān)屬性
Activation Track是軌道的顯示名稱,Post-playback state表示Timeline播放完后游戲?qū)ο蟮臓顟B(tài)
名稱 | 描述 |
---|---|
Active | 播放完激活游戲?qū)ο?/td> |
Inactive | 播放完后隱藏游戲?qū)ο?/td> |
Revert | 游戲?qū)ο蠡謴?fù)到播放之前的激活狀態(tài) |
Leave As Is | 保持最后一幀的狀態(tài) |
點(diǎn)擊時(shí)間軸上的片段,在Inspector上可以看到片段相關(guān)信息,片段的開始時(shí)間,結(jié)束時(shí)間,持續(xù)時(shí)間,分別以秒和幀為單位顯示
點(diǎn)擊??圖標(biāo)(快捷鍵M),會(huì)將軌道鎖定,不能操作,這是為了防止誤觸,此時(shí)軌道還是生效的
點(diǎn)擊??圖標(biāo)(快捷鍵L),會(huì)將軌道禁用,此時(shí)軌道不生效,當(dāng)有多條軌道時(shí),可以禁用其中幾條軌道,方便對(duì)其他軌道操作
Control Track
和 Activation Track 類似,控制對(duì)象是否激活,在一條軌道上可以控制多個(gè)對(duì)象是否激活,而 Activation Track 一條軌道只能控制一個(gè)對(duì)象是否激活,直接把場景中的對(duì)象拖動(dòng)到時(shí)間線上即可
點(diǎn)擊片段,查看相關(guān)設(shè)置
名稱 | 描述 |
---|---|
Source Game Object | 場景中綁定的的游戲?qū)ο蠡騪refab |
Control Activation | 勾選才會(huì)控制對(duì)象的激活狀態(tài) |
Control Playable Directors | 是否控制其他的Playable Director |
Control Particle Systems | 是否將控制粒子系統(tǒng) |
Random Seed | 為粒子系統(tǒng)提供的隨機(jī)種子 |
Control ITimeControl | 是否控制實(shí)現(xiàn)ITimeControl接口的Monobehaviours |
Control Children | 是否控制子對(duì)象中的粒子系統(tǒng),Playable Director |
Audio Track
Audio Track控制聲音播放,可以不用指定Audio Source,在時(shí)間線上右鍵Add From Audio Clip選擇聲音片段即可,也可以直接把聲音片段拖到時(shí)間線上,拖動(dòng)兩個(gè)片段使其重疊,重疊部分(斜線部分)就是融合,會(huì)在兩個(gè)片段之間做一個(gè)平滑過渡
點(diǎn)擊上方Play按鈕即可聽到聲音
點(diǎn)擊聲音片段,在Inspector界面上會(huì)顯示片段相關(guān)屬性
名稱 | 描述 |
---|---|
Ease In Duration 和 Blend Out Duration | 控制過渡時(shí)間 |
Clip In | 設(shè)置片段從第幾秒開始播放 |
Speed Multiplier | 設(shè)置播放速度倍速 |
Blend Curves | 過渡曲線控制融合時(shí)的變化速度,默認(rèn)使用Auto,也可以切換到Manual受到控制曲線 |
Clip | 片段資源引用 |
Loop | 是否循環(huán) |
Volume | 聲音大小 |
Animation Track
控制游戲?qū)ο髣?dòng)畫的播放
使用已有動(dòng)畫,首先要把場景中帶有Animator的對(duì)象拖入槽位中,然后把這個(gè)對(duì)象相關(guān)的動(dòng)畫片段拖入時(shí)間線上,雙擊這個(gè)動(dòng)畫片段就可以打開Animation窗口,對(duì)動(dòng)畫做細(xì)致的調(diào)整
自己制作幀動(dòng)畫,先點(diǎn)擊Start recording按鈕進(jìn)入編輯狀態(tài),拖動(dòng)時(shí)間軸,修改對(duì)象身上的屬性,此時(shí)這個(gè)動(dòng)畫片段是Infinite Clip,即無限長的片段,需要把它轉(zhuǎn)換成有限長的片段
右鍵Convert To Clip Track就會(huì)把它轉(zhuǎn)換成有限長片段
Signal Track
建立Timeline與外部系統(tǒng)的溝通渠道
Signal Asset 信號(hào)資源:用于發(fā)射器和接收器之間的聯(lián)系,可以在多個(gè)Timeline實(shí)例中復(fù)用
Signal Emitter 信號(hào)發(fā)射器:包含對(duì)信號(hào)資源的引用,可以在Markers,Signal Track或其他軌道上添加
Signal Receive 信號(hào)接收器:設(shè)置觸發(fā)的方法
在任意軌道的時(shí)間線上右鍵Add Signal Emitter,添加一個(gè)信號(hào)發(fā)射器
第一次添加會(huì)有感嘆號(hào)提示沒有信號(hào)資源,點(diǎn)擊Create Signal 創(chuàng)建一個(gè)信號(hào)資源,點(diǎn)擊Add Signal Receiver會(huì)在軌道綁定的物體上添加Signal Receiver組件
以后創(chuàng)建發(fā)射器就可以通過下拉列表來選擇信號(hào)資源
名稱 | 描述 |
---|---|
Retroactive | 表示如果Timeline的播放開始于Signal Emitter的時(shí)間之后,是否仍然觸發(fā)信號(hào) |
Emit Once | 為True表示在循環(huán)期間只發(fā)出一次此信號(hào) |
在Signal Receiver上指定觸發(fā)的方法,這里用一個(gè)簡單的腳本進(jìn)行測試
public class TimelineTest : MonoBehaviour
{
public void OnTimelineStart()
{
// 禁用輸入
Debug.LogError("start");
}
public void OnTimelineEnd()
{
// 恢復(fù)輸入
Debug.LogError("end");
}
}
這里創(chuàng)建兩個(gè)信號(hào)資源Start Signal和End Signal,在Timeline的開始和結(jié)尾添加兩個(gè)發(fā)射器,分別指定信號(hào)資源是Start Signal和End Signal,在接收器中設(shè)置相應(yīng)方法,這個(gè)就可以在Timeline的開始和結(jié)束觸發(fā)OnTimelineStart和OnTimelineEnd方法,游戲中播放Timeline時(shí)通常會(huì)禁止玩家的輸入操作,可以在這兩個(gè)方法中添加禁用和恢復(fù)的邏輯,這個(gè)方法最多帶一個(gè)參數(shù)
點(diǎn)擊軌道上的Track Markers可以展開或收起發(fā)射器
Playable Track 及自定義軌道
Timeline是由Track(軌道),Clip(片段),Behavior(行為),Mixer(混合器)四元素組成
Track | 每一行是一個(gè)軌道 |
---|---|
Clip | 軌道上的片段 |
Behavior | 片段在軌道上的行為邏輯 |
Mixer | 兩個(gè)片段應(yīng)該怎樣融合 |
使用Playable Track實(shí)現(xiàn)自定義代碼邏輯,至少需要定義Clip和Behavior這兩個(gè)元素對(duì)應(yīng)的腳本
右鍵 -> Create -> Playables 可以創(chuàng)建Clip和Behavior這兩個(gè)元素的腳本模板,會(huì)自動(dòng)填充一些常用方法,其中Playable Asset C# Script就是對(duì)應(yīng)Clip
當(dāng)Timeline開始播放時(shí),會(huì)創(chuàng)建名為Playable的節(jié)點(diǎn),Playable直譯為可播放的,它是和時(shí)間有關(guān)的,如一段音樂,一段動(dòng)畫,一段Timeline,Timeline本身也是Playable可以嵌入到別的Timeline中。多個(gè)Playable被組織成一種樹狀結(jié)構(gòu),稱為PlayableGraph。對(duì)于每一幀,Timeline都會(huì)對(duì)該圖進(jìn)行采樣,以讀取和混合多個(gè)數(shù)據(jù)源(動(dòng)畫、音頻等),Mixer會(huì)根據(jù)每個(gè)Clip的權(quán)重去混合得到最后的結(jié)果
這里演示創(chuàng)建Clip和Behavior腳本來控制Light光照變化
using UnityEngine;
using UnityEngine.Playables;
[System.Serializable]
public class LightClip : PlayableAsset
{
// 由于PlayableAsset是個(gè)Asset資源,它不能直接引用場景中的對(duì)象
// 在PlayableAsset中,public修飾的引用類型,只可以選擇Project中的對(duì)象
// ExposedReference暴露引用,允許在Hirearchy面板上引用場景中的燈光
public ExposedReference<Light> light;
public Color lightColor;
public float lightIntensity;
// Factory method that generates a playable based on this asset
public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
{
// 工廠方法創(chuàng)建playable,這個(gè)playable屬于傳入的graph
var playable = ScriptPlayable<LightBehaviour>.Create(graph);
// 獲取這個(gè)LightBehaviour
var lightBehavior = playable.GetBehaviour();
// 將light變量解析為一個(gè)光源對(duì)象,graph.GetResolver()方法獲取一個(gè)上下文對(duì)象,
// 然后根據(jù)這個(gè)對(duì)象的引用表來查找light變量對(duì)應(yīng)的光源對(duì)象
lightBehavior.light = light.Resolve(graph.GetResolver());
lightBehavior.lightColor = lightColor;
lightBehavior.lightIntensity = lightIntensity;
return playable;
}
}
Timeline運(yùn)行第1幀時(shí)會(huì)調(diào)用上面的CreatePlayable方法創(chuàng)建Playable對(duì)象,playable.GetBehaviour() 獲取Behaviour并賦值就是克隆數(shù)據(jù)
// A behaviour that is attached to a playable
public class LightBehaviour : PlayableBehaviour
{
public Light light;
public Color lightColor;
public float lightIntensity;
// Called when the owning graph starts playing
public override void OnGraphStart(Playable playable)
{
// 獲取這個(gè)playable關(guān)聯(lián)的PlayableDirector組件
var playableDirector = playable.GetGraph().GetResolver() as PlayableDirector;
}
// Called when the owning graph stops playing
public override void OnGraphStop(Playable playable)
{
}
// Called when the state of the playable is set to Play
public override void OnBehaviourPlay(Playable playable, FrameData info)
{
if (light == null)
return;
light.color = lightColor;
light.intensity = lightIntensity;
}
// Called when the state of the playable is set to Paused
public override void OnBehaviourPause(Playable playable, FrameData info)
{
}
// Called each frame while the state is set to Play
public override void PrepareFrame(Playable playable, FrameData info)
{
}
//在片段上的每一幀調(diào)用,兩個(gè)片段之間的空隙不會(huì)調(diào)用
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
// playable是Clip創(chuàng)建的
Debug.LogError("已播放時(shí)間:" + playable.GetTime() + " 持續(xù)時(shí)間" + playable.GetDuration());
// FrameData是幀信息,當(dāng)需要這一幀的時(shí)間增量,可以使用 info.deltaTime
Debug.LogError("時(shí)間增量" + info.deltaTime);
// playerData 是綁定的對(duì)象
var go = playerData as GameObject;
if (go)
{
var light = go.GetComponent<Light>();
}
}
}
這樣就可以在Playable Track上右鍵添加LightClip,開始運(yùn)行時(shí)就會(huì)調(diào)整燈光的顏色和強(qiáng)度
上面的代碼因?yàn)橐脠鼍爸械臒艄?,所以在Clip中定義了參數(shù)變量,然后把變量傳遞給Behavior,如果只使用值類型變量,還有另一種寫法,把Behavior序列化,作為Clip的成員變量,這里以TimeDilationTrack的相關(guān)代碼為例
[Serializable]
public class TimeDilationBehaviour : PlayableBehaviour
{
public float timeScale = 1f;
}
[Serializable]
public class TimeDilationPlayableAsset : PlayableAsset
{
[NoFoldOut] // 移除折疊,并繪制所有的子屬性
public TimeDilationBehaviour template = new TimeDilationBehaviour();
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
return ScriptPlayable<TimeDilationBehaviour>.Create(graph, template);
}
}
Clip 實(shí)現(xiàn) ITimelineClipAsset 接口可以控制片段上顯示的信息,可以使用 ClipCaps.All 來顯示全部信息
[System.Serializable]
public class LightClip : PlayableAsset, ITimelineClipAsset
{
public ClipCaps clipCaps => ClipCaps.All;
//...
}
自定義軌道
自定義軌道LightTrack,并設(shè)置軌道只能添加LightClip類型的片段
using UnityEngine;
using UnityEngine.Timeline;
[TrackColor(20/255f, 200/255f, 50/255f)] //設(shè)置軌道前的顏色
[TrackClipType(typeof(LightClip))] //軌道能添加什么類型的片段
[TrackBindingType(typeof(GameObject))] //指定軌跡需要綁定到的對(duì)象類型
public class LightTrack : TrackAsset
{
}
自定義混合器
這里使用TimeDilationTrack相關(guān)代碼說明,Mixer是在Track中創(chuàng)建的
[TrackColor(0.855f, 0.8623f, 0.87f)]
[TrackClipType(typeof(TimeDilationPlayableAsset))]
public class TimeDilationTrack : TrackAsset
{
// Creates a runtime instance of the track, represented by a PlayableBehaviour.
// The runtime instance performs mixing on the timeline clips.
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
return ScriptPlayable<TimeDilationMixerBehaviour>.Create(graph, inputCount);
}
}
創(chuàng)建混合器的Playable是鋪滿整個(gè)時(shí)間線的,包含那些沒有片段的地方
Mixer也是PlayableBehaviour,也有ProcessFrame方法,在樹形結(jié)構(gòu)體中Mixer是Clip的父節(jié)點(diǎn),會(huì)先調(diào)用Clip綁定的Behavior中的ProcessFrame方法(如有),然后調(diào)用Mixer中的ProcessFrame方法,如果片段需要混合,那只實(shí)現(xiàn)Mixer中的ProcessFrame方法即可
Mixer在ProcessFrame中遍歷所有的Clip,并獲取每個(gè)Clip的權(quán)重,根據(jù)權(quán)重混合得到最后的結(jié)果
如圖,當(dāng)Timeline播放到第一個(gè)Clip時(shí),這個(gè)Clip的權(quán)重為1,后面兩個(gè)Clip的權(quán)重為0
當(dāng)播放到Clip2時(shí)(未混合),Clip權(quán)重為0,Clip2權(quán)重為1,Clip3權(quán)重為0
當(dāng)播放到Clip2和Clip3混合時(shí),Clip權(quán)重為0,Clip2權(quán)重 + Clip3權(quán)重 = 1
public class TimeDilationMixerBehaviour : PlayableBehaviour
{
private float m_DefaultTimeScale = 1;
// Called every frame that the timeline is Evaluated.
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
// inputCount表示這條軌道上有幾個(gè)Clip
int inputCount = playable.GetInputCount();
float timeScale = 0f;
float totalWeight = 0f;
// blend clips together
for (int i = 0; i < inputCount; i++)
{
// 獲取第i個(gè)Clip的權(quán)重
float inputWeight = playable.GetInputWeight(i);
ScriptPlayable<TimeDilationBehaviour> playableInput = (ScriptPlayable<TimeDilationBehaviour>)playable.GetInput(i);
TimeDilationBehaviour input = playableInput.GetBehaviour();
// 混合邏輯
timeScale += inputWeight * input.timeScale;
totalWeight += inputWeight;
}
// blend to/from the default timeline
Time.timeScale = Mathf.Max(0.0001f, Mathf.Lerp(m_DefaultTimeScale, timeScale, Mathf.Clamp01(totalWeight)));
}
// Called when the playable graph is created, typically when the timeline is played.
public override void OnPlayableCreate(Playable playable)
{
m_DefaultTimeScale = Time.timeScale;
}
// Called when the playable is destroyed, typically when the timeline stops.
public override void OnPlayableDestroy(Playable playable)
{
Time.timeScale = m_DefaultTimeScale;
}
}
Cinemachine Track
如果安裝了Cinemachine,會(huì)有這個(gè)軌道控制Cinemachine相機(jī)之間的切換,場景中創(chuàng)建兩個(gè)虛擬相機(jī),分別看向Cube的左側(cè)和右側(cè),把虛擬相機(jī)拖到時(shí)間線上自動(dòng)生成片段
拖動(dòng)兩個(gè)片段使其重疊,重疊部分就是融合,它會(huì)對(duì)兩個(gè)相機(jī)之間的屬性做插值,做一個(gè)平滑過渡
Samples
在官方的案例中還有幾個(gè)軌道可以用
TextTrack
TextTrack用于修改文本內(nèi)容,可以做字幕,點(diǎn)擊片段設(shè)置字色,字號(hào),文本內(nèi)容
修改Ease In Duration和Ease Out Duration增加淡入淡出效果
TimeDilationTrack
這個(gè)軌道修改 Time.timeScale,點(diǎn)擊片段設(shè)置 timeScale 的值,運(yùn)行到片段時(shí)會(huì)修改Time.timeScale的值,片段之外的地方恢復(fù)到默認(rèn)值1
Time.timeScale 控制全局時(shí)間,會(huì)影響到動(dòng)畫,視頻等,一般用于實(shí)現(xiàn)慢動(dòng)作
Video Track
將視頻片段直接拖到時(shí)間線上就行,重疊部分也有融合效果
名稱 | 描述 |
---|---|
Video Clip | 視頻片段引用 |
Mute | 是否靜音 |
Loop | 是否循環(huán) |
Preload Time | 視頻開始預(yù)加載視頻流之前的時(shí)間量 |
Aspect Ratio | 視頻的長寬比 |
Render Mode | 視頻內(nèi)容將被繪制在哪里,相機(jī)的遠(yuǎn)剪裁面或近剪裁面 |
Target Camera | 指定要渲染到哪個(gè)相機(jī),沒有指定,則使用主相機(jī) |
Audio Source | 指定一個(gè)可選的音源 |
Tween Track
設(shè)置對(duì)象在兩個(gè)Transform之間位移,旋轉(zhuǎn)
Should Tween Position 勾選表示改變指定對(duì)象的位置
Should Tween Rotation 勾選表示改變指定對(duì)象的旋轉(zhuǎn)
插件 Default Playables
這是官方提供的免費(fèi)插件,包含一些其他軌道,地址
LightControlTrack
這個(gè)軌道和上面實(shí)現(xiàn)的自定義軌道 LightTrack 類似,控制燈光顏色強(qiáng)度,實(shí)現(xiàn)燈光混合疊加效果,但一個(gè)軌道只能控制一個(gè)光源
TextSwitcherTrack
和上面案例中的 TextTrack 類似,可以做字幕
TimeDilationTrack
和上面案例中的 TimeDilationTrack 一樣,實(shí)現(xiàn)慢動(dòng)作
TransformTweenTrack
和上面案例中的 Tween Track 類似,控制對(duì)象的移動(dòng)旋轉(zhuǎn)
ScreenFaderTrack
控制圖片的顏色漸變
NavMeshAgentControlTrack
控制物體在導(dǎo)航網(wǎng)格上移動(dòng),這里創(chuàng)建一個(gè) Plane 烘焙網(wǎng)格
創(chuàng)建一個(gè)膠囊體添加 NavMesh Agent 組件作為需要移動(dòng)的物體,創(chuàng)建一個(gè)空物體,用它 Transform 作為移動(dòng)的終點(diǎn)
膠囊體放入軌道槽位,片段上引用目標(biāo)位置
運(yùn)行才能看到效果
Timeline Playable Wizard
這是幫助我們生成 Timeline 4 個(gè)元素的的工具
填寫好軌道名稱,設(shè)置軌道綁定類型,參數(shù)等就可以生成4個(gè)元素對(duì)應(yīng)的腳本
PlayableGraph Visualizer
這是官方的一個(gè)可視化工具,顯示 Timeline 或 Animator 中的樹形結(jié)構(gòu)
通過 Package Manager 安裝,git 地址輸入 https://github.com/Unity-Technologies/graph-visualizer.git
安裝后在 Window -> Analysis 下會(huì)有入口
點(diǎn)開后會(huì)顯示Timeline上每個(gè)軌道的相關(guān)信息
插件Material Timeline Track
這是資源商城的插件,提供了兩個(gè)軌道,可以在 Timeline 上修改材質(zhì)的屬性,地址
Material Track
使用 Animation Track k動(dòng)畫時(shí),可以記錄數(shù)值類型,枚舉類型的修改,但是貼圖的修改不會(huì)記錄下來
使用 Material Track 可以獲取材質(zhì) Shader 中的所有屬性進(jìn)行修改
Renderer Track
這個(gè)軌道綁定含有 Renderer 組件的對(duì)象,只會(huì)修改綁定對(duì)象的材質(zhì)屬性,不會(huì)影響到相同材質(zhì)的其他對(duì)象
參考
官網(wǎng)文檔
通過實(shí)際案例演示學(xué)習(xí)Timeline
Playable API:定制你的動(dòng)畫系統(tǒng)文章來源:http://www.zghlxwxcb.cn/news/detail-714941.html
Timeline Unity3d 教程文章來源地址http://www.zghlxwxcb.cn/news/detail-714941.html
到了這里,關(guān)于Unity Timeline及其相關(guān)插件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!