? 一本视频在线中文字幕一区二区,欧美国产一卡二在线播放,GOGOGO大但人文艺术
聯(lián)系我們

給我們留言

聯(lián)系我們

地址:福建省晉江市青陽街道洪山路國際工業(yè)設(shè)計園納金網(wǎng)

郵箱:info@narkii.com

電話:0595-82682267

(周一到周五, 周六周日休息)

當(dāng)前位置:主頁 > 3D教程 > 圖文教程

Unreal Engine 4 動畫系統(tǒng)介紹

來源: 納金網(wǎng) | 責(zé)任編輯:傳說的落葉 | 發(fā)布時間: 2019-05-15 08:37 | 瀏覽量:

       Unreal Open Day 2017 活動上 Epic Games 資深開發(fā)者支持工程師王禰先生為到場的開發(fā)者介紹了在 Unreal Engine 4 中動畫系統(tǒng),以下是演講實錄。 

 

       大家好!鑒于引擎移動端功能以及 UI 優(yōu)化都有同事做了介紹,今天我選擇講的主題是關(guān)于動畫。動畫是一個非常復(fù)雜的系統(tǒng),我會主要介紹一些基本的概念,大家在了解了基本概念后,就可以在上面做出擴(kuò)展。我并不會教大家怎么使用動畫工具,關(guān)于一些動畫節(jié)點的使用,我們的在線文檔上都有比較詳細(xì)的說明,也有比較多的資源。今天不會講到的內(nèi)容包括 Morph target,IK,Retargeting,Rootmotion,Additive,Skeletal Control 這些。

 

       首先,我們先來看看引擎中的動畫系統(tǒng)是如何工作的。為什么我要先講解這樣一個問題,因為國內(nèi)有很多用戶在使用動畫系統(tǒng)的時候,有很多疑問。這些疑問并不是因為他們沒有查閱文檔,而是因為沒有理解系統(tǒng)的工作方式。本質(zhì)上,動畫系統(tǒng)工作原理是非常簡單的,我這里還是重新介紹一下。

 

112520umwph25ail3ew5k1


我們先來看看在引擎中動畫相關(guān)的資源主要分為哪幾類。

 

       第一大類是最基本的數(shù)據(jù)資源。其中主要來自于外部 DCC 工具制作并導(dǎo)入的原始資源,我們稱之為 Anim sequence。

 

       然后,有些資源可能為了制作和導(dǎo)入的方便是分散開來的,但是有些情況下會組合到一起使用。所以引擎中有一種資源叫 Anim Composite。他是使用多個 Anim sequence 或是自身(Anim Composite)所組合成的資源。在使用時,依然被看作是普通的 Anim Sequence。

 

       第三種數(shù)據(jù)資源類型叫 Blendspace。他可以是一維的也可以是二維的。二維的情況下,在兩個軸上,通過變量控制對任意在二維平面上指定的動畫序列(Anim sequence)作混合。對于任意的二維輸入,總能找到這個輸入值在二維圖像附近最接近的四個動畫序列按照權(quán)重來混合。嚴(yán)格來說,Blendspace 并不是單純的基礎(chǔ)數(shù)據(jù),他也受其它輸入?yún)?shù)的影響來混合 Pose 。但是,由于在動畫混合藍(lán)圖中是作為 Pose 的輸入結(jié)點,我們這里依然把它作為數(shù)據(jù)類資源。

 

       第四種數(shù)據(jù)資源叫 Montage。這一類資源一般是直接受邏輯控制的組合資源。

 

       在數(shù)據(jù)資源的基礎(chǔ)上,我們還可以綁定一些額外的數(shù)據(jù)。

 

       第一類常用的數(shù)據(jù)類型叫 Notify。引擎包括一些內(nèi)建的 Notify類型。譬如,在走路的時候希望腳步踩到地面的那一刻,觸發(fā)踩地面的事件,用來向地面投射貼花,用于產(chǎn)生腳印,以及播放腳步音效或揚起塵土的特效之類。這里的 Notify 你還可以擴(kuò)展成你自定義的事件類型,可以在藍(lán)圖以及代碼中去處理事件對應(yīng)的邏輯。舉個例子:如果做一個動作或格斗類游戲,在出招的時候,判定并不是從這個動畫開始播放的時刻就已經(jīng)有了的,可能是從出招動畫到某一時刻開始,才有打擊判定。那么我們就可以通過 Notify 來用事件通知游戲邏輯在特定的時候去打開和關(guān)閉判定。

 

       第二類叫 Curve。Curve 就是伴隨動畫序列的時間軸所綁定的曲線數(shù)據(jù),后面會有一些舉例。再然后你也可以綁定一些你自定義的數(shù)據(jù)類型。

 

112520omtkujtcv3sydk3d

?

?        講完剛剛這些數(shù)據(jù)類型,接下來就是最重要的處理動畫混合邏輯的資源,叫 Anim instance。Anim sequence 的設(shè)計是基于對于 3A 級游戲中復(fù)雜的動畫需求所產(chǎn)生。這里有一個假設(shè),那就是動畫狀態(tài)在復(fù)雜的情況下一定是需要對骨骼結(jié)構(gòu)有認(rèn)知的。所以引擎中的 Anim instance 和骨骼是強(qiáng)耦合的關(guān)系。譬如你需要知道腰部的骨骼位置來區(qū)別開上半身和下半身的動畫,這樣的設(shè)計可以完成相當(dāng)復(fù)雜的動畫混合,但是卻也帶來了一些限制。如果我的整個動畫狀態(tài)只需要簡單的一個狀態(tài)機(jī)在不同的狀態(tài)中,譬如閑置、追逐、攻擊、受擊、死亡,在每中狀態(tài)中,并不作復(fù)雜的混合,而只是播放一個簡單的 Anim instance。在整個邏輯中完全不需要用到骨骼信息。那么照理來說,即使擁有不同骨骼結(jié)構(gòu)的對象,如果只需要這個簡單邏輯的話都可以共享這套邏輯。然而由于我剛剛所說的 Anim instance 和骨骼的強(qiáng)耦合設(shè)計導(dǎo)致在現(xiàn)在的引擎框架下,這樣的功能暫時無法完成。我們在內(nèi)部也在作一些討論,以后可能會有支持純邏輯的 Anim instance 功能,而目前來看,如果大家有這樣的需求,我建議在可能的情況下把這些對象的骨骼層次結(jié)構(gòu)盡可能保持一致,這并不是說多個對象的骷髏要完全一致,而只是骨骼樹的層次結(jié)構(gòu)一致就可以了。譬如你的基礎(chǔ)骨骼是個人形,有些怪物會多出尾巴或翅膀,這些多出的骨骼并不破壞原先的樹狀結(jié)構(gòu),而只是多出來的分支。所以還是可以利用 Retargeting 來共享 Anim instance 的邏輯。

 

112520luobl969mf9mfmnf

?        Anim instance 中,最明顯的兩塊分別是 EventGraph 和 AnimGraph。其中 EventGraph 就類似于普通的藍(lán)圖,用來在 tick 的時候處理一些邏輯狀態(tài)的更新以及播放 Montage。當(dāng)然這些邏輯也可以在 C++里面做。AnimGraph 是用來混合和輸出 Pose 的地方。說到混合,我們可以把每一幀中整個混合的過程看成是一棵樹,從葉子結(jié)點輸出的 Pose 經(jīng)過枝干結(jié)點的混合計算輸出到根結(jié)點的最終 Pose。我們剛剛說到的數(shù)據(jù)類的資源,就是這里所謂的葉子結(jié)點。這些結(jié)點本身不需要其它的 Pose 作為輸入,而直接提供了 Pose 的輸出。而枝干結(jié)點則是進(jìn)行混合的結(jié)點,當(dāng)然真的說混合也不是很準(zhǔn)確,有些枝干結(jié)點只需要輸入一個 Pose,在自己的結(jié)點邏輯中,對這個 Pose 作一些修正,并不進(jìn)行混合。我們把這些枝干結(jié)點計算調(diào)整和混合 Pose 的行為稱作評估(evaluate)。舉個最簡單的枝干結(jié)點的例子,那就是多結(jié)點混合。譬如,輸入的有兩個 Pose ,一個權(quán)重是 0.8,另一個是 0.2,相當(dāng)于是把第一個 Pose 的 BoneMap 的 transform 乘以 0.8,第二個乘以 0.2,再相加輸出。這里我列了一個樹狀圖,來表示動畫混合的過程。但是因為這是個非常簡化了的例子,所以其中不包括直接對骨骼進(jìn)行控制或者直接 Override 一個 Fullbody slot 來強(qiáng)制更新整個 BoneMap 之類的行為。并且一般來說,一個正常的 anim graph 的一幀的混合也不會像這張簡化圖這樣是棵紅黑樹。首先,就像我剛剛說的,你并不能保證他是二叉的,譬如剛剛說的多混合結(jié)點完全可以由三個或以上結(jié)點來混合,以及我剛剛說的有些枝干結(jié)點,只有一個輸入。再者,大部分情況下他也不會是平衡的。在混合狀態(tài)復(fù)雜的情況下,我們一般會分層次來混合,這就導(dǎo)致了這棵混合樹會往一個分支方向衍生出去。

112520slx8kdlyekvkswf2


       好了,那么剛剛看到的是單幀的 Pose 混合計算情況。當(dāng)持續(xù)到多幀以后,情況又會稍微復(fù)雜一些。譬如說兩個 Pose 混合起來,他們的長度很有可能不一樣。舉例,我有一個走路的動畫,他可能長達(dá) 2 秒,同時我又有一個跑步的動畫,他長達(dá) 1 秒。如果我直接混合,就會出現(xiàn)很怪異的情況,譬如走路還在邁左腿的時候,跑步已經(jīng)邁右腿了,混合起來的姿勢就會非常奇怪?;谶@種情況,我們引入了 Sync Groups 的概念,當(dāng)我們設(shè)置這兩個動畫序列在同一個 Sync Groups 下進(jìn)行混合時,引擎會把當(dāng)前混合時權(quán)重較高的作為領(lǐng)導(dǎo),把剩下的序列縮放到和領(lǐng)導(dǎo)序列一樣長的情況,再按比例去做混合。這樣就能解決動畫長度不一致的混合問題。

 

112520c4vjql5jjll9qgj8


       再來看多幀動畫狀態(tài)下,如果狀態(tài)復(fù)雜,動畫樹上的某些分支在不同的幀內(nèi)是完全不同的狀態(tài)。為了簡化樹的邏輯,動畫混合系統(tǒng)中可以使用狀態(tài)機(jī)來隔離每一幀的狀態(tài)。我這里的圖例舉了一個比較簡單的 Locomotion 的狀態(tài)機(jī)。

 

       關(guān)于動畫混合的這棵樹,在復(fù)雜的情況下,我們還會把他做分層。也就是把一棵混合完的樹的根結(jié)點緩存下來,作為另一棵樹的葉子結(jié)點。當(dāng)然你也可以把整個復(fù)雜的樹連到一起,分層只是為了便于維護(hù)和調(diào)整。這個圖片是我們的 MOBA 游戲《虛幻爭霸》中一個角色分層混合的模版示例。


112521qh5m9fyv9clifylf

?講完了動畫的基礎(chǔ)概念后,我們來看一些例子加深理解。

 

112521k82n352h5gldi8d2

 

       子樹類用例。在引擎中有一類功能叫 Sub anim instance。這就類似于剛剛說到分層里面的一棵子樹,這個子樹可以擁有一個輸入結(jié)點,并且輸出一個 Pose 。典型的應(yīng)用方式,是把在同一個邏輯下有多種可替換的子邏輯分離開,做到不同的 Sub anim instance 中。這樣可以把剩余的邏輯用來共享。通過替換不同的 Sub anim instance 來組合出最終不同的效果。

 

112521ysc77hxsq7qhdxtp

 

       接下來講一些葉子類的用例。通常的葉子類結(jié)點就是我們剛剛說的數(shù)據(jù)類結(jié)點,我這里舉兩個比較特殊的例子。在 4.17 版本中,我們會加入一個叫 live link 的結(jié)點。它通過引擎的消息總線從外部實時讀入數(shù)據(jù)輸出 Pose 。這里的輸入源可以是各種 DCC 工具,也可以是動作捕捉或手勢識別類設(shè)備。在我們放出的第一個版本中,會帶有一個 maya 的實現(xiàn),通過 maya 的插件把在 maya 中當(dāng)前動畫的 BoneMap 數(shù)據(jù)通過 live link 消息總線和引擎進(jìn)行通信。引擎把接收到的數(shù)據(jù)轉(zhuǎn)換成引擎內(nèi)的數(shù)據(jù)輸出當(dāng)前的 Pose 。這樣就可以做到在 maya 中一邊播動畫一邊在引擎中看到效果了。

 

112521bjnnr0cp5vndqf88


        下一個葉子類結(jié)點的舉例,叫 Pose Snapshot。Pose Snapshot 就是把任意指定幀的 BoneMap 記錄下來,在接下來的任意時刻,用來作為數(shù)據(jù)源輸入和其它 Pose 做混合。譬如在 Robo Recall 中,你打倒了機(jī)器人,機(jī)器人會進(jìn)入物理狀態(tài)而倒地。你可以把這個狀態(tài)存下來,在之后再和站起來的動畫作混合。

 

        剛剛舉了兩個葉子類結(jié)點的例子,我們再來看看動畫混合中最大的一類——枝干類結(jié)點的例子。大部分情況都是多個 Pose 按權(quán)重進(jìn)行混合,當(dāng)然也可以是按照 bool、int、enum 值進(jìn)行混合。我這里依然舉一些特殊的例子。


112522coj17o01070gjkx4

 

?       第一個例子是 RigidBody 結(jié)點。在講這個結(jié)點前,我要先介紹一個伴隨而來的概念,叫 immediate mode physics。引擎中以前的 Physics 是所有的 RigidBody 都加到同一個 PhysX scene,這種情況下如果每個角色身上都有多個需要計算物理的 RigidBody,場景中又有大量的這樣的角色,計算量就相當(dāng)?shù)拇蟆5谴蟛糠謺r候角色互相之間的物理碰撞細(xì)節(jié)大家并不關(guān)心,所以這樣的效率比較低。

 

112522g8zt4zmm7fmzgq72


?       因此我們和 Nvidia 進(jìn)行了合作,他們對 PhysX 的 Api 進(jìn)行了調(diào)整。在新版本中放出了更底層的 Api 可以讓我們在引擎中做更細(xì)致的控制。大家可以看到這個新的 immediate physics,一個角色身上所有的 RigidBody 都只注冊在當(dāng)前這個 skeletal mesh component 下,多個 SMC(skeletal mesh component 縮寫)之間并不會有交互,這樣很大程度上提高了運行的效率。

 

112522r2auwpos2svuwarg

 

       大家可以看到,這里的視頻同屏有幾百個小兵站在地上做閑置的動畫,在受到物理沖擊后轉(zhuǎn)入到物理狀態(tài)。這么大量的物理對象在我的筆記本上依然能穩(wěn)定在 60 幀,而右邊的圖也顯示了單個較為復(fù)雜的角色在模擬物理時候的開銷,只使用了 0.24ms。大家可能覺得這是一個純粹物理的功能,為什么我放到動畫的枝干結(jié)點的例子里來講呢? 因為事實上你可以在動畫中把動畫計算完的 Pose 輸入進(jìn)去,在這個結(jié)點中根據(jù)當(dāng)前動畫的 Pose 和前一幀計算完的結(jié)果計算出骨骼結(jié)點的變化,從而模擬出物理受力的變化,并根據(jù)輸入的權(quán)重混合回你的 Pose 。有了這樣的功能,做我之前說的 Robo Recall 中很自然的擊倒機(jī)器人或者拳擊類的游戲、以及用槍射擊怪物時怪物比較自然的受擊都變得相當(dāng)簡單。


112522xiua66eu6i6neau6

 

       好了,下面我們再來看另一個枝干結(jié)點的例子。我們稱之為 Speed Warping。傳統(tǒng)的游戲中如果你調(diào)整了移動速度,那么為了不產(chǎn)生滑步你也需要調(diào)整跑步的動畫播放的速率。譬如你的速度翻了一倍,那么很多時候你就需要把動畫也加快一倍播放,大家可以看到在這里的視頻右邊加快播放后的動畫其實是很別扭的。真實情況下我們提高速度除了邁出的腳步速度會有一些變快以外,更多的情況下,其實是調(diào)快了步幅。同樣的減慢速度也是這樣。所以 Speed Warping 就是做了這么一個效果。那我們是怎么計算的呢??

 

112522rbvwp6hrisi1v3si

 

?       簡單來講,原始的動畫雙腳的位置是這里的紅球。我們計算他跟腰部垂線的水平距離并根據(jù)加減速的倍率橫向擴(kuò)展。譬如當(dāng)是 2 倍的時候,調(diào)整到綠球的位置。但這個時候兩只腳的距離被拉的太長了,因此我們適當(dāng)?shù)耐抡{(diào)整了屁股的位置,并且將兩只腳以剛才綠球所在位置到屁股的連線上挪動一段距離使得腳步的長度保持不變,所以最終計算出來的就是藍(lán)球的位置。

 

112523lr399u3ev1epo3te


       我再舉一些其它的例子。比如引擎中當(dāng)你對 AnimBP 進(jìn)行繼承的時候,所創(chuàng)建出來的內(nèi)容叫 Child AnimBP ——它所做的事情是讓你重載所有的葉子類結(jié)點。舉個實用的例子:譬如我有一種敵人,他永遠(yuǎn)是從初始的出現(xiàn)狀態(tài)到發(fā)現(xiàn)玩家到向玩家攻擊這樣轉(zhuǎn)化,而這樣的怪物在地圖上不同的場景下有不同的出現(xiàn)動畫,有可能是從地上爬出來的,有可能是從墻上跳出來的。對于這個怪物來說,他的動畫切換狀態(tài)都是一樣的,所不同的只是初始狀態(tài)所需要使用的資源,所以只需要替換初始的動畫(某個葉子結(jié)點)就可以了。

 

112523z73ll555pbggk7m1

 

       再舉一個例子,有不少人問過,在《虛幻爭霸》中,是怎么做到讓角色不滑步的。傳統(tǒng)的主機(jī)游戲中,為了讓腳不滑步很多時候我們都是使用 root motion 來做移動的動畫。但是因為《虛幻爭霸》是個 MOBA 游戲,策劃會希望能夠用數(shù)據(jù)來驅(qū)動移動的速度。譬如在有不同的 buff 或者裝備的情況下,角色的速度也會發(fā)生變化,這用 root motion 就很不好處理。所以我們做了一個叫 Distance Curve 的功能,這也是我剛剛說到的 Curve 數(shù)據(jù)的一種運用方式。我們可以把 Distance Curve 的方式看成是反向的 root motion。它通過給所有的啟動、旋轉(zhuǎn)、站定動畫都加入曲線數(shù)據(jù),曲線上的數(shù)值表示當(dāng)前這幀動畫到達(dá)站定點的位置的距離,其中站定點(Marker)是很容易預(yù)測的。?

 

 

112523k3ww6f3l11wnnjwp

 

相關(guān)文章
網(wǎng)友評論

您需要登錄后才可以發(fā)帖 登錄 | 立即注冊

關(guān)閉

全部評論:0條

推薦
熱門