Skip to content

回歸到遊戲的開發

用Timeline呈現對話

October 20, 2019

目前手邊的工作項目裡,需要進行過場時的對話功能。雖然可认進行的方式有很多種,但想到Unity在2017年引用強大的過場機制-Timeline到快2020年了,都還沒有試著在專案中引用過,而這次的過場對話需求,就恰恰的符合了動機、時機。但從來沒有碰過Timeline,網路上眾多的資訊很著重在動畫的表現上,而動畫的展演不是本身的強項,只好先從自己可以接受了解的方式進行。

預想中的過場對話,先用三個步驟呈現

  1. 揭開對話序幕
  2. 對話開始
  3. 結束閉幕

一開始的嘗試,用一個Timeline來展現,一開始會先將UI的黑色背景開啓,而後過一段時間會開啓對話UI,再一段時間後,則一起關閉。

流程上是符合現有的三個步驟,但真實的運作上,第二步驟有個不同於Timeline的用法,Timeline的使用概念會偏向時間導向且確定會發生的編排。揭開對話序幕的準備基本上時可以按照時間進行安排,然而,當對話開始時,在範例的安排下,可以限制其對話呈現時間,但正式專案裡,對話的長度會隨著劇情而有字數的長短。而這會影響到結束閉幕的時間。

且不同於此範例,正式專案中,對話會有多個,因此會被重覆進行Clip的開關。在現有的調整下,可以依據其時間長度來進行開啓對話、關閉對話的動作。不過這似乎需要某種事件的機制,當Clip完成後進行通知,對UI進行適當的處理。

將Activation Track裡的Clip弄成了三個進行測試,並額外加入了Signal Track,在相對應的對話UI Activation Clip結束的時間點放入了Signal,並調整成時間不等長的方式進行模擬。執行起來真有一些感對話流動的感覺。

到此,若過場的對話沒有複雜的樹狀結構,僅以線性方式進行,現階段所實驗的就可以滿足。只需用Post Processing的方式在Editor裡將一段段的對話用不同的Timeline包起來,也就是產生Timeline Asset後再保存下來。而於遊戲進行中,依照所需的Timeline進行播放,能符合簡易的需求。

心中的另一個想法是如果可以用State的概念進行切分,產生三個Timeline分別代表開始準備、對話和結束,或許可以不用額外進行將一段段對話產生一個個Timeline,也就是利用State概念所製作出來的Timeline,可以大幅度縮減至只需三個Tiemline?

利用三個Timeline分別操控相關的UI,加入適當的Signal進行事件通知,並利用三個Director進行播放。對話僅有一個時表現上和一開始只用一個Timeline類似,這似乎是個不錯的調整,方向上有可能是正確的。

但緊接著要處理的問題就是對話有多句時,又回到如何利用這個分切成State的使用方式?第一直覺是關閉再開啓第二個Timeline,直到完成所有的對話。但接下來就是如何達成?

複製這個單線進程的進度後,展開了加入CutSceneManager的功能,由此Manager做狀態機的轉換中心,當第一個Timeline結束後,開始展開對話用Timline,並於此處放入相對應的台詞,對話Timeline結束後CutSceneManager依據是否還有更多的對話內容請對話Timeline重新播放,直到沒有任何對話時,則讓收尾用Timeline開始。

實際嘗試時有二個需要注意的重點。

其一,對話Timeline必需要重置,才能正常播放,而重製的訊息可由此篇討論中了解。而對應的程式碼為

conversationText.text = e;
// Restore timeline
_playableDirector.time = 0;
_playableDirector.Stop();
_playableDirector.Evaluate();
// Play timeline
_playableDirector?.Play();

其二,複製時連同Signal Asset一起多了一份,但Unity不會區別這份和之前的那份有什麼差異,照理說複製後Asset的GUID會改變,Unity應該會知道這是不同份,然而SignalReceiver元件那的下拉選單裡的資訊並不會多出一份,有可能是Signal是用名稱進行區別,雖然它們擺在不同的資料目錄中,但檔名相同。之後要特別注意Signal Asset的名稱和使用,免得於正式專案裡會產生麻煩。

利用外部狀態串連Timeline的概念,可以達到預想中的效果,可說是不錯的進展,但是否能夠利用ControlTrack或是PlayableBehaviour完成相同的功能,或是應該利用這些機制才是較為正確的做法?

這次的實驗就先在此處打住,不論方法是否符合Unity規劃的用法,但這次嘗試中,找到了二個方式可以進行過場純對話的展演。

  • 後製對話資料做成一段段Timeline,並由執行時決定要播放哪個Timeline
  • 利用狀態概念切分Timeline,並由執行時將對話內容塞進來

Timeline的了解應該還要再花上一些時間,像是對話之間的Fading要怎麼呈現等,會是接下來了解的重點。

這次的實碼專案放置於unity-sample-2019中的dialouge-through-timeline,共分為四個階段的嘗試。


This is where ApprenticeGC goes.
Or whatever, you make the rules.