Unity3D如何實現RPG遊戲中的劇情?

現在在做一款RPG遊戲,想知道如何實現RPG遊戲中的劇情,目前實現了對話系統,但是在實際開發過程中發現,對話系統需要和人物動畫、攝像機鏡頭等多個方面進行耦合,我希望能夠通過外部的配置文件來配置這些細節,使用腳本來進行處理,不知道大家有沒有什麼好方法?


如果你可以認同代碼即數據,c#就是一個不錯的腳本語言兩個觀點的話,請往下看:

首先需要明確劇情系統的目標:

劇情所要解決的核心問題就是:

如何調度不同的系統來處理分布在時間軸上面的劇情命令;

核心解決思路就是兩個:

系統分層和協程。

如同拍攝電影一樣,製作RPG遊戲的劇情需要有不同的系統協作:

最重要的是導演,負責調度控制劇情流程,而劇情的具體流程類似於劇本,電影工業中劇本的書寫方法是:

首先確定拍攝的環境地點,人物

接著一行,一行描述,對話,鏡頭,人物的相關行為;

我們的目標就是,將劇情的配置方式完全參考電影劇本來做,採用命令模式描述就是:

場景 10006 野外1;

創建玩家在 100 100點上;

創建怪物在 110 110點上;

UI展示劇情對話1,玩家頭像,內容 你好呀;

UI展示劇情對話2,怪物頭像,內容 天氣真好;

玩家對象 發動攻擊;

延遲1s;

創建攻擊粒子;

拉近盡頭到玩家手上;

要實現上面這種基於命令的配置方式,需要實現以下內容:

系統分層:

對話,UI,鏡頭控制,角色控制等是遊戲中的不同系統,這些不同系統對外提供一些介面,用於實現對劇情展示的支持;

導演劇本:

針對每個劇情書寫特定的劇本,可以設計一種 領域特定語言,來編寫類似於與上面的劇情命令腳本;

開發量更小的方法,使用unity自帶的協程來書寫,類似於這樣:

IEnumerator StoryProgress()

yield return StartCoroutine(CreatePlayer());

yield return StartCoroutine(CreateMonster()):

yield return StartCoroutine(ShowUI("Hello world"));

yield return StartCoroutine(WaitForEvent("MonsterDie"));

}

這樣一個導演劇本是獨立於所有系統的,只負責組織和操控其它系統;

通過協程我們可以實現,等待特定事件,等待某個操作結束,等待一定時間,而這3個能力,就可以實現一個優雅的線性的劇情描述了。

而只需要在合適的時候,執行上面的 StoryProgress,就可以做到通過特定的事件來觸發特定的劇情。

當然你需要注意一點,在播放劇情之前,可能需要對當前遊戲環境進行清理,例如網路遊戲中,隱藏其它玩家,隱藏其它不相關怪物,等等。

而要開發相關的劇情編輯器的功能就是,將編輯好的時間軸生成相關的StoryProgress的c#代碼即可。

至此一個優雅的劇情系統就完成了。

一個簡單參考實現:

http://my.oschina.net/u/186074/blog/528266

當然上面描述了這些,只解決了一個底層問題,即如何組織一個劇情故事;

而上層問題是,如何設定在合適的條件下,觸發某個劇情,設計思路如下,首先設定某個劇情,在滿足哪些條件的情況下觸發;

例如:滿足和Npc1對話過,和Npc2對話過,要和Npc3對話,背包裡面有物品item1;

而劇情觸發經常是在處理要和Npc3對話時,對條件進行檢測;

因此需要在系統中存系統的條件變數,例如主線任務進行到某一步的條件變數;

當和某個NPC對話時,觸發劇情檢測,若條件變數滿足,則觸發劇情。

因此需要設計:主動觸發劇情檢測的觀察點,系統的條件變數,以及 滿足哪些條件觸發某個劇情相關配置。

舉幾個檢測點的例子:

1:在和某NPC對話時檢測劇情條件是否成立;

2:在進入場景的時候檢測劇情條件是否成立;

3:在進入某個區域時檢測劇情條件是否成立;


Asset Store搜索Dialogue System和Cinema Director。

Asset Store

https://www.assetstore.unity3d.com/en/#!/content/19779

人家都做得很完善了,何必重複發明輪子。


蟹妖, 都閃開, 上面的回答都沒有做過大型劇情, 我曾經做過一個端游,劇情動畫超過10分鐘的片段不在少數。

首先寫劇情腳本不要用狀態機,不要各種ifelse,當我們說一個動畫腳本 「一個人從床上起來,拿起劍走出門外」 的時候,裡面包含一堆狀態機和條件判斷,從床上起來需要播動畫,需要等待動畫結束,然後走到劍的旁邊,需要等待走到。。。。,這裡面每個動作和行為之間銜接,都要判斷,寫得不好就是一堆ifelse,寫的稍微好點的就是狀態機, 但不可避免的涉及一個問題就是如何優雅的等待某動作、事件完成?

正確姿勢是co-routine,用timeline驅動,導出為lua程序代碼,導出時檢查合法性,稍後上圖說明之前做的一個director程序(要回去找找),專門做劇情腳本,策劃用過都說是神器。

最後就是如何在unity3d里用lua了,哈哈,當然是用我開源的Slua | Fastest static lua binding for Unity3D.

對於Unity3D, 為啥不生成c#代碼?因為劇情是資源更好,可以隨時更新,甚至從網路傳輸過來。


吐槽下我之前的項目。 當時拿了個很簡單的角色走位和對話然後跟我說劇情系統的功能這樣就好了。 我實現了這個劇情編輯器給策劃使用後就變成了這樣.....

=。=


直接寫腳本不會死的。看看星際遊俠同學自己實現的配置文件,這個配置文件可讀性還不如腳本,能做的功能也比腳本差遠了,寫錯了也沒有語法檢查,很難調試。

腳本的可讀性不好那是自己寫的不好,有各種寫代碼的技巧來重構。其他東西都包裝成函數,這段腳本裡面只要保留一系列動作就可以了。


剛開始學Unity的時候傻傻的自己寫,直接導致我們的劇情策劃「累覺不愛」,順便提下,我是按照星際爭霸的劇情編輯器做的,主要分三層:

事件層

條件層

動作層

監聽事件、判斷條件、執行動作。

如果讓我再選一次,我會嘗試用USequencer


設置流程值啊,設置各種開關呀。劇情推動了,流程值就增大。然後各個NPC根據流程值來做齣劇情響應。


贊同首贊推薦的工具。

不會使用可以參考一下官方的教程。

或者視頻教程:

【技術分享】如何在unity加入人物對話推動劇情_野生技術協會_科技_bilibili_嗶哩嗶哩


我曾經自己用腳本寫過一個小的結構,做預設物和劇本樹。純用的腳本一步一步走,用時間推動,有分支就有選擇。

缺點:這樣寫所有的東西都是可以自己定義和處理,但也使得整個劇情的設計都比較麻煩需要考慮的東西很多啊。細節處理很費事。劇本樹-劇本幀-劇本幀行為內容-劇本幀行為內容的內容這樣的結構在做劇情的時候有點費事了。

優點:因為完全手工製作的,所以各個部分都有什麼能幹什麼就比較好編輯(都是預設物)。比較自由的跳轉,結合配置文件可以隨意跳轉劇情,劇本內容比較容易復用。

這個比較適合劇本各種改的情況。但是我用這個結構弄了一個30分鐘的劇情累夠嗆,真的是挺麻煩的。

看了你們的想法我覺得我應該也把我這想法說出來,雖然只是一個很糟糕的東西。算是一個早期思路吧。


我之前的做法是創建一些component表示控制流及驅動3c的指令。通過gameobject組織故事樹,存成prefab。觸發劇情時調對應prefab就行了。缺點是沒有編輯器;優勢是可熱更新,可直接測試單獨的劇情片段,所有劇情策劃自己就能搞定 。


unity cutscene插件


如果要把劇情跟其他事件剝離開封裝起來,那麼只用寫腳本就可以了。否則最好通過事件行為樹跟配置表來做


為什麼不設計兩個config文件?

一個保存api,一個保存劇情流及跳轉(一般就二叉樹跳轉)。

幾個基本假設定了,整個劇情就有了。

動態生成的也可以錄製config文件。

俗話說好記性不如爛筆頭嘛。


推薦閱讀:

為什麼從事遊戲行業會被人覺得是不務正業?
你為什麼不會離開遊戲行業?
遊戲軟體開發的工作是怎樣的?
任天堂是否在吃老本?
哪些遊戲提升了你對遊戲的審美?

TAG:遊戲設計 | 遊戲開發 | Unity遊戲引擎 | 角色扮演遊戲RPG |