1. 程式人生 > >Unity3D 劇情動畫的實現(一)

Unity3D 劇情動畫的實現(一)

最近在利用U3D進行劇情動畫的製作,要求是可以控制人物移動,播放動作,有對話,整個劇情動畫都是由一個文字驅動的。因此具有較高的靈活性,而且也易於拓展,可以完全丟給策劃去配置。

下面簡單地介紹一下我的是如何實現的,主要是講下思路,留給以後的自己看,當筆記記著,免得忘記

整個劇情繫統的運作,有點類似狀態機,是通過一個事件去觸發另一個事件的發生,我把劇情動畫中,所有可能出現的事件都列出來,發現,劇情動畫只需要一下4種事件,就可以拼湊出一個簡易的劇情動畫

1.幕頭事件:用於表示一段劇情的開始,這裡面可以定義許多你想要在這一段劇情中,一些固定的資料,比如,這段劇情需要載入哪個場景,有哪些模型等

2.人物控制事件:用於定義一個人物的移動行為,怎麼移動,移動到哪裡,播放什麼動畫等

3.對白事件:用於定義一個對白事件,誰說話,說話的內容,說話時的動作等

4.鏡頭控制事件:用於控制鏡頭的行為,比如,播放鏡頭動畫,或者是如何移動鏡頭

以上四種類型的事件,基本上可以拼湊出一個簡單的劇情動畫,舉個例子:

鏡頭中只有人物B,突然有一個人物A,匆忙地跑到人物B面前,然後和B說,有人來敲門了。接著鏡頭從慢慢地朝向門的方向(就是看著門)。就這樣一段小劇情,其實整個過程可以分割成這樣

一。幕頭定義(事件1):有人物A,人物B,房間的場景

二。人物移動(事件2):人物B從某一點,移動到另一點,同時播放跑步動作

三。對白事件(事件3):進行對白,B和A說,有人來敲門

四。鏡頭移動(事件4):讓攝像機播放一個鏡頭移動的動畫

然後通過劇情繫統,讓這四個事件按順序執行,就像狀態機一樣,從一個狀態轉換到另一個狀態,執行的順序是:

先執行  事件1, 等事件1執行完畢後,觸發事件2,然後事件2,等事件2執行完畢後,執行事件3,以此類推

因為當時在做的時候,就有利用一些狀態機的特性,所以,我定義這四個事件的類的時候,是這樣定義的


因此這四個事件都具有相同的方法,分別是

1.Begin():在這個事件開始前,進行的一些初始化動作

2.Update():這個事件所需要做的具體邏輯

3.Exit():在事件完成時,最後需要做的事情

學過狀態機的人,應該都看得出,其實這就是一個狀態基類的一些常規方法

至於這寫函式裡面的邏輯,暫時先不寫了,要是有人需要,我再補上

最後,是劇情繫統的類的定義,我這個也採用了一些狀態機的一些方法。

劇情繫統,主要是用來執行每個事件的Begin,Update,Exit等函式:

    /// <summary>
    ///  初始化劇情動畫U
    /// </summary>
    private void Awake()
    {
		event.Begin(); // 開啟某一個事件
    }
	void Update () {
        if (m_allEnvent.Count <= 0) // 沒有任何事件可以執行,表示整個劇情動畫結束
        {
            ForceCloseStory();  // 結束整個劇情
            return;
        }
        // 執行所有事件
        for (int i = 0; i < m_allEnvent.Count; ++i) // m_allEnvent是所有正在發生的事件的一個事件列表
        {
            if (m_allEnvent[i].Update()) // 執行Update函式,如果返回TRUE則表示事件結束,需要進入Exit
            {
                m_allEnvent[i].Exit();
            }
        }
	}
以上程式碼是我臨時寫的虛擬碼,只是為了表達一下,劇情繫統的運作原理,具體的邏輯程式碼,可以參照有限狀態機的實現,其實大體差不多。

最後來總結一下整個思路,首先是分割劇情動畫中,包含哪些事件,然後進行提煉,封裝成一個動畫事件。然後通過觸發的方式,去觸發別的事件,觸發的數量不一定是一個,你同時觸發很多個事件。然後把這些動畫事件類,都通過劇情繫統來一一執行邏輯。

最後,是如何變成文字驅動,其實可以把所有的一些可變動資料,都當成一個成員變數,然後通過文字讀取資料,對每個成員進行賦值。

比如,人物控制事件,它包含一個移動起始點,移動結束點,移動的速度,需要播放的動作名稱,人物的Rota值等。

這些都可以通過自己定義讀取方式,讀取文字,然後賦值。