Unity2017中Timeline的簡單使用方法
Timeline是Unity2017版本中新加入的功能,可以非常方便的進行場景動畫的建立和修改,包括物體、聲音、粒子、動畫、特效、自定義Playable以及子Timeline等多種資源進行整合,從而能夠較方便的生成效果很棒的場景動畫,同時可以通過Unity的Recorder資源包錄製較為完整的視訊並匯出。
1.Timeline介面簡單介紹
在Unity2017中,點選Window->Timeline即可調出Timeline面板。如下圖所示:
在該面板中,可以建立多種型別的片段,如果你匯入AssetStore中的Default Playables資源包(其中預置了多個官方提供的簡單Playable例項),其面板如下所示:
其中常用的主要有
- Activation Track(控制物體的顯示和隱藏)
- Animation Track(為物體加入動畫,可以在場景中方便地錄製動畫,也可以是已經制作好的Animation Clip)
- Audio Track(為動畫新增音效,並可對音效進行簡單的裁剪和操作)
- Control Track(在該軌道上可以新增粒子效果,同時也可以新增子Timeline進行巢狀)
- Playable Track(在該軌道中使用者可以新增自定義的播放功能)
- Track Group(將不同的軌道進行分類,相當於資料夾功能)
當我們建立了TimeLine後,會在指定位置生成TimeLine的檔案*.playable,當選中該檔案後,會在Inspector面板中看到其相應的屬性,如下圖所示:
其中Frame Rate可以設定該Timeline每秒鐘播放多少幀動畫。Duration Mode分為Based On Clips和Fixed Length兩種模式,Based On Clips模式為按照幀數來播放,當播放到最後一幀時結束播放,Fixed Length模式可以設定總共播放多長時間,當播放到指定時間是停止。Duration設定當前播放的秒數和幀數。
2.Timeline軌道簡單介紹
2.1 Activation Track
該軌道首先需要為其賦值一個GameObject,表示該軌道控制該物體的顯示與隱藏,當在Timeline播放過程中,如果處於片段內部,則該物體顯示,否則該物體隱藏。
當我們點選該軌道時,會在Inspector面板中看到可以設定的屬性,如下所示:
- Active(當Timeline播放結束時,將該物體啟用,設定為顯示狀態)
- Inactive(當Timeline播放結束時,該物體取消啟用,設定為隱藏狀態)
- Revert(當Timeline播放結束時,該物體還原Timeline在第1幀時的啟用狀態)
- Leave As Is(當Timeline播放結束時,該物體保持在Timeline最後一幀的啟用狀態)
2.2 Animation Track
Animation Track主要控制動畫的播放,包括動畫片段、幀動畫等。當我們點選Animation Track時,可以設定其屬性,如下圖所示:
2.2.1 Animation Track 屬性
- Apply Avatar Mask(啟用“阿凡達遮罩”,當啟用後將根據選擇的遮罩應用在整個軌道中)
- Avatar Mask(選擇需要的遮罩,並將其應用在當前Animation軌道中)
最終效果如下:
- Apply Track Offsets(啟用軌道偏移效果,將所有動畫的起始位置都設定為指定的偏移角度和位置上,與動畫片段中的Clip Root Motion Offsets功能類似)
- Clip Offset Match Fields(該選項可以設定不同動畫之間偏移可匹配的變換)
2.2.2 動畫軌道使用簡介
1.新增Animation Clip
右擊Animation Clip的空白處,選擇Add From Animation Clip即可從已有的動畫片段中選擇。
可以拖拽動畫片段調整播放的時間,同時也可以將多個動畫片段進行疊加來完成動畫過渡效果。
2.錄製動畫
可以在Animation Clip中點選紅色按鈕進行錄製,通過設定不同的屬性來為物體設定關鍵幀,從而完成不同型別的動畫製作。
3.設定曲線
錄製的動畫可以在動畫視窗中開啟,在動畫視窗中可以通過關鍵幀點的方式進行控制,也可以通過曲線的方式進行控制。
2.3 Audio Track
Audio Track主要控制動畫中的音效,可以設定聲音的起始時間、結束時間、淡入時間、淡出時間、播放速度、不同音效間的混合效果、是否迴圈播放等。其屬性如下所示:
2.4 Control Track
Control Track主要控制與時間有關的元素,如粒子效果、Timeline等。
該軌道可以在指定的父物體下例項化一個Prefab,並對該Prefab中與時間有關的元素進行播放操作。
2.5 Playable Track
Playable Track允許使用者自定義相關動畫效果,在Default Playables資源包中包含了一部分自定義的功能軌道,包括文字、時間、燈光、位置、尋路、淡入淡出等效果,使用者也可以根據自己的需要進行定製化開發,以實現更加複雜的效果。
使用者可以在程式碼中繼承PlayableBehaviour和PlayableAsset兩個類,在其中完成自定義的動畫功能。
/// <summary>
///該類主要實現在TimeLine的PlayableTrack中顯示我們定義的功能,並完成賦值
/// </summary>
public class PlayableBehaviourSample : PlayableAsset
{
//使用ExposedReference進行賦值操作
public ExposedReference<GameObject> ShowNumberText;
private Text text;
public int startNum;
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
var scriptPlayable = ScriptPlayable<PlayableTest>.Create(graph);
//從ExposedReference中獲取我們需要的控制元件
text = ShowNumberText.Resolve(graph.GetResolver()).GetComponent<Text>();
//對指定的PlayableBehaviour中的屬性進行賦值
scriptPlayable.GetBehaviour().ShowNumberText = text;
scriptPlayable.GetBehaviour().StartNum = startNum;
return scriptPlayable;
}
}
/// <summary>
/// 讀秒功能
/// </summary>
public class PlayableTest : PlayableBehaviour
{
//顯示文字的控制元件
public Text ShowNumberText;
public int StartNum;
float time;
int currentNum;
/// <summary>
/// 當該PlayableBehaviour的PlayableGraph啟動時呼叫
/// </summary>
/// <param name="playable"></param>
public override void OnGraphStart(Playable playable)
{
base.OnGraphStart(playable);
Debug.Log("OnGraphStart Called");
currentNum = StartNum;
ShowNumberText.text = "Start Number Is " + StartNum;
Debug.Log(ShowNumberText.text);
}
/// <summary>
/// 當該PlayableBehaviour的PlayState轉換為PlayState.Play時呼叫
/// </summary>
/// <param name="playable"></param>
/// <param name="info"></param>
public override void OnBehaviourPlay(Playable playable, FrameData info)
{
base.OnBehaviourPlay(playable, info);
Debug.Log("OnBehaviourPlay Called");
}
/// <summary>
/// 該函式與ProcessFrame函式功能相同,都是在該PlayableBehaviour播放的每一幀中呼叫,相當於Update函式的功能
/// </summary>
/// <param name="playable"></param>
/// <param name="info"></param>
public override void PrepareFrame(Playable playable, FrameData info)
{
base.PrepareFrame(playable, info);
Debug.Log("PrepareFrame Called");
time += Time.deltaTime;
if (time > 1.0f)
{
currentNum++;
ShowNumberText.text = "Current Number Is " + currentNum;
Debug.Log(ShowNumberText.text);
time -= 1.0f;
}
}
/// <summary>
/// 該函式與PrepareFrame函式功能相同,都是在該PlayableBehaviour播放的每一幀中呼叫,相當於Update函式的功能
/// </summary>
/// <param name="playable"></param>
/// <param name="info"></param>
/// <param name="playerData"></param>
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
base.ProcessFrame(playable, info, playerData);
Debug.Log("ProcessFrame Called");
}
/// <summary>
/// 該函式在PlayableBehaviour片段的PlayState轉換為Delay時呼叫
/// </summary>
/// <param name="playable"></param>
/// <param name="info"></param>
public override void OnBehaviourDelay(Playable playable, FrameData info)
{
base.OnBehaviourDelay(playable, info);
Debug.Log("OnBehaviourDelay Called");
}
/// <summary>
/// 該函式在PlayableBehaviour片段的PlayState轉換為Pause時呼叫
/// </summary>
/// <param name="playable"></param>
/// <param name="info"></param>
public override void OnBehaviourPause(Playable playable, FrameData info)
{
base.OnBehaviourPause(playable, info);
Debug.Log("OnBehaviourPause Called");
ShowNumberText.text = "End Number Is " + currentNum;
Debug.Log(ShowNumberText.text);
}
/// <summary>
/// 該函式在PlayableBehaviour片段停止播放時呼叫
/// </summary>
/// <param name="playable"></param>
public override void OnGraphStop(Playable playable)
{
base.OnGraphStop(playable);
Debug.Log("OnGraphStop Called");
}
/// <summary>
/// 該函式在PlayableBehaviour片段建立時呼叫
/// </summary>
/// <param name="playable"></param>
public override void OnPlayableCreate(Playable playable)
{
base.OnPlayableCreate(playable);
Debug.Log("OnPlayableCreate Called");
}
/// <summary>
/// 該函式在PlayableBehaviour片段銷燬時呼叫
/// </summary>
/// <param name="playable"></param>
public override void OnPlayableDestroy(Playable playable)
{
base.OnPlayableDestroy(playable);
Debug.Log("OnPlayableDestroy Called");
}
/// <summary>
/// 該函式在PlayableGraph的PrepareData階段被呼叫
/// </summary>
/// <param name="playable"></param>
/// <param name="info"></param>
public override void PrepareData(Playable playable, FrameData info)
{
base.PrepareData(playable, info);
Debug.Log("PrepareData Called");
}
}
以下為執行後的呼叫順序
以下為該Timeline設定的狀態,主要部分為PlayableTrack。
最終執行效果如下:
該方法也可通過繼承BasicPlayableBehaviour類完成,但是在未來的版本中該類可能會被PlayableBehaviour和PlayableAsset類取代。
遇到的問題
在使用TimeLine功能的過程中,如果對物體使用了錄製功能進行位置的調整,很多情況下物體的預設位置會發生偏移,最好在使用TimeLine的Animation Track錄製功能前先備份場景,以免在設定動畫過程中對場景造成破壞。
本人對TimeLine很多功能還不夠熟悉,這些只是在使用過程中用到的功能,將Timeline和CineMachine以及Post Processing等功能進行結合可以做出相當炫酷的效果,可參考Unity官方的Adam&Neon動畫短片。
如有問題歡迎大家提出,今後有時間會再簡單介紹CineMachine和Post Processing相關內容。