久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

狀態(tài)機(jī),?大錯(cuò)特錯(cuò),!動(dòng)作游戲的動(dòng)作系統(tǒng)是這樣做的

 秋刀錄 2023-07-15 發(fā)布于北京
圖片
本文非常長(zhǎng),并且涉及部分專業(yè)知識(shí),。建議先馬后看,。如果還沒(méi)關(guān)注我們,記得關(guān)注一下哦,。
01  什么是動(dòng)作游戲的動(dòng)作系統(tǒng)
動(dòng)作游戲的動(dòng)作系統(tǒng)指的就是管理游戲中每個(gè)角色動(dòng)作的系統(tǒng),。我們通常理解的“這個(gè)動(dòng)作做完了切換到下一個(gè)動(dòng)作”,,屬于動(dòng)作系統(tǒng)的功能之一,畢竟“動(dòng)作切換”這件事情,,不僅是動(dòng)作游戲才有的,,即便是回合制游戲,只要需要角色做不同的動(dòng)作,,就會(huì)面臨動(dòng)作切換問(wèn)題,。而相比于非動(dòng)作游戲,動(dòng)作游戲的動(dòng)作系統(tǒng),,還有更多核心的細(xì)節(jié),,也正是這些細(xì)節(jié)導(dǎo)致他不能用傳統(tǒng)的回合制游戲的狀態(tài)機(jī)的方式來(lái)開(kāi)發(fā)。那么,,動(dòng)作游戲有哪些獨(dú)特的細(xì)節(jié)呢,?

NO.1

幀是時(shí)間的單位

我們把游戲中的一個(gè)Tick認(rèn)為是一幀,而對(duì)于每個(gè)角色來(lái)說(shuō),,每個(gè)tick當(dāng)前的“狀態(tài)”就是一個(gè)Frame,,也稱之為“一幀”,只不過(guò)是“角色的一幀”,,而非Tick(“游戲的一幀”),。在一個(gè)游戲里面,確切地說(shuō)是任何游戲的邏輯世界里面(而非渲染),,幀都應(yīng)該是最小時(shí)間單位,,因此游戲世界里的時(shí)間概念是“運(yùn)行了多少幀”,而非“幾秒”,,在這里外行和內(nèi)行之間有一個(gè)分水嶺——外行會(huì)認(rèn)為幀和秒之間的匯率是一個(gè)十分重要的數(shù)字,,因?yàn)槿绻?幀之間的現(xiàn)實(shí)時(shí)間差過(guò)大,會(huì)引起不流暢的問(wèn)題,。但是根本的問(wèn)題就在于,,邏輯世界中的時(shí)間單位和顯示時(shí)間單位未必要有個(gè)匯率,,也就是說(shuō)2幀之間間隔了多少現(xiàn)實(shí)時(shí)間的單位,對(duì)于游戲邏輯而言是沒(méi)有意義的——假如我們把現(xiàn)實(shí)時(shí)間以秒作為最小時(shí)間單位(以int而非float計(jì)算),,我們吃一口蘋果需要2秒,那么2秒到底是不是真的“均勻”的2秒,,秒與秒之間時(shí)間差真的相等嗎這些問(wèn)題我們下意識(shí)的都不會(huì)去思考,,我們確信他們是相等的,因此在做游戲的時(shí)候,,我們也要確信2個(gè)邏輯幀之間時(shí)間就是相等的,,因?yàn)檫壿嫀褪亲钚r(shí)間單位。

圖片

幀作為最小時(shí)間單位,,會(huì)導(dǎo)致一些錯(cuò)誤的依賴于動(dòng)畫(huà)的做法在動(dòng)作游戲中出現(xiàn)問(wèn)題,。邏輯依賴于渲染的典型表現(xiàn)就是我們把邏輯寫(xiě)在Update里面,,并且用deltaTime(這甚至是一個(gè)float)去運(yùn)算間隔了多久,,然后算個(gè)插值——這樣的做法完全搞混或者含糊掉了邏輯幀的概念,,因?yàn)樗欢ㄒ堰壿嫀惋@示做個(gè)運(yùn)算,以至于一下tick運(yùn)行了原本應(yīng)該很多tick做的事情,,即便是unity的FixedUpdate這樣的湊效果(FixedUpdate實(shí)際上是在Update的時(shí)候for循環(huán)的運(yùn)行了好幾次Tick),,也比直接Tick依賴于Update(每個(gè)Update是1個(gè)Tick)來(lái)的更適合游戲,。

圖片

(Cancel讓動(dòng)作切換變的更連貫了)

那么這個(gè)Tick問(wèn)題導(dǎo)致的錯(cuò)誤會(huì)是什么呢,?我們說(shuō)“動(dòng)作游戲中每一幀都是一個(gè)不一樣的世界”,我可能在游戲的第328幀進(jìn)入一個(gè)僅有2幀的Cancel點(diǎn),,此時(shí)我按下對(duì)應(yīng)的按鍵可以打出Combo,,但是如果是Update的模式,很可能這個(gè)2幀因?yàn)樗惴ǘ^(guò)了,,比如策劃需要FPS是60的游戲,那么錯(cuò)誤的實(shí)現(xiàn)方式中,,我們會(huì)把1/60秒當(dāng)做一個(gè)單位,,然后如果一個(gè)Update走了0.1秒,那么就直接把6幀當(dāng)做一個(gè)Tick處理了,,而不是for循環(huán)走10次,,這樣一來(lái)我們就完全錯(cuò)過(guò)了這個(gè)Combo的機(jī)會(huì)了;同樣的在《艾爾登法環(huán)》等一些偽動(dòng)作游戲中,,也會(huì)發(fā)生因?yàn)榭D導(dǎo)致一個(gè)Update時(shí)間過(guò)長(zhǎng),,而錯(cuò)過(guò)了攻擊判定框生效的時(shí)間而無(wú)法命中敵人。而在類似喀普康最新的格斗游戲《街霸6》等經(jīng)典的動(dòng)作,、格斗游戲中,,這樣的QTE型的連招又是很核心的玩法,因此“幀是最小時(shí)間單位”是一個(gè)要做這樣的游戲必須貫徹的基礎(chǔ)思想,,也是一個(gè)游戲開(kāi)發(fā)者對(duì)于游戲最基本的理解,。

NO.2

“下一幀是什么”而非“下一個(gè)動(dòng)作是什么”

正如上文所說(shuō),動(dòng)作游戲中“每一幀都是不一樣的世界”,,因此對(duì)于每一個(gè)角色來(lái)說(shuō),,每一幀的邏輯數(shù)據(jù)都是和上一幀沒(méi)有直接的因果關(guān)系的,他們之間在邏輯上是并非連續(xù)的——上一幀我還在重拳的第12幀,,這一幀可能就是升龍的第8幀,,因?yàn)橛幸粋€(gè)Cancel關(guān)系,導(dǎo)致動(dòng)作游戲動(dòng)作切換會(huì)有“加速”的效果,,并且讓玩家十分爽快,。而在非動(dòng)作游戲中,“一個(gè)動(dòng)作(美術(shù)上的動(dòng)作)”才是一個(gè)單位,這個(gè)動(dòng)作在什么條件下進(jìn)入哪一個(gè)動(dòng)作——是非動(dòng)作游戲?qū)τ趧?dòng)作切換的理解,。
圖片盡管從抬杠的角度來(lái)看,,你可以把兩者都說(shuō)成是“符合條件就切換到對(duì)應(yīng)動(dòng)作,只是能切換到的動(dòng)作數(shù)量多點(diǎn)少點(diǎn)”,,但是這兩者的根本邏輯是截然相反的——?jiǎng)幼饔螒蚴敲恳粠荚谶\(yùn)算我的下一幀是什么,;而非動(dòng)作游戲,是等待一個(gè)通知告訴我要不要試試看換某個(gè)動(dòng)作,,如果等不到這個(gè)通知,,就按照預(yù)設(shè)的“下一個(gè)動(dòng)作”來(lái)確定轉(zhuǎn)換到什么動(dòng)作。
假如說(shuō)游戲中“切換動(dòng)作”這個(gè)需求簡(jiǎn)單到真的只是“符合了某個(gè)條件就切”,,那么這兩個(gè)做法都是沒(méi)有問(wèn)題的,,可是動(dòng)作游戲中,藏著更多玩家無(wú)法直觀看清,,但確確實(shí)實(shí)可以提會(huì)到的“隱藏需求”,,比如《街霸6》中的Combo等。

圖片

這些乍一看“通知系統(tǒng)”也可以做到,,但實(shí)際上存在著非常多的隱患,在下文中,,我們通過(guò)實(shí)現(xiàn)的思路就能看清楚這里“說(shuō)不清道不明”(所以才有這么多人搞不清楚)的細(xì)節(jié),。
這里要順帶提一下一個(gè)名詞解釋——Cancel:在動(dòng)作游戲中,,假如我(角色)當(dāng)前處于A動(dòng)作的第x幀,這并不是A動(dòng)作的最后一幀,,此時(shí)我發(fā)動(dòng)了另外一個(gè)動(dòng)作B,,結(jié)束了動(dòng)作A,并且從B動(dòng)作的y幀開(kāi)始繼續(xù)動(dòng)作,,這樣一來(lái)A動(dòng)作切換到B動(dòng)作,,但是動(dòng)作長(zhǎng)度卻低于A動(dòng)作長(zhǎng)度+B動(dòng)作長(zhǎng)度,以達(dá)到了一個(gè)“快速切換”或者“加速”的效果,,這在動(dòng)作游戲和格斗游戲領(lǐng)域中被稱為“Cancel”,。而Cancel本身也是動(dòng)作游戲動(dòng)作切換“手感好”的核心要素,這是用狀態(tài)機(jī)幾乎無(wú)法實(shí)現(xiàn)的(不是說(shuō)硬湊不出來(lái),,就看平白多了幾百倍的工作量能不能接受吧),。

NO.3

同一個(gè)“狀態(tài)”有不同的動(dòng)作

通常當(dāng)我們沒(méi)有經(jīng)驗(yàn)的開(kāi)發(fā)人員乍一想的時(shí)候,,都會(huì)認(rèn)為一系列動(dòng)作可以對(duì)應(yīng)為一個(gè)狀態(tài),,而一個(gè)狀態(tài)也可以對(duì)應(yīng)多個(gè)動(dòng)作,只要達(dá)到“一個(gè)狀態(tài)有豐富的動(dòng)作可選”這個(gè)標(biāo)準(zhǔn),,狀態(tài)機(jī)就萬(wàn)無(wú)一失了,。這個(gè)想法在即時(shí)回合制游戲,,比如diablo系列、魂系,、無(wú)雙系列、FF7Remake等游戲中是說(shuō)的通的,,因?yàn)樗麄儽举|(zhì)上都是一個(gè)時(shí)間自動(dòng)推進(jìn)的回合制游戲(ATB),他們都可以以“一個(gè)動(dòng)作”為一個(gè)邏輯單位,,不涉及非常細(xì)節(jié)的動(dòng)作切換,,因此你完全可以定義出一些狀態(tài)來(lái)描述動(dòng)作,比如“普通攻擊”,,他可以是平砍3連,、4連,、5連什么的,幾連都是平砍,,并且順序一定是這樣的——1后面是2后面是3后面是4,,頂多有個(gè)buff可能讓你1235之類的順序,而從游戲設(shè)計(jì)的角度出發(fā),,策劃本身想的也是“普通攻擊”就是“普通”的和技能不一樣,。
但是動(dòng)作游戲他不太一樣,動(dòng)作游戲設(shè)計(jì)思想上本身就是角色每個(gè)動(dòng)作是等價(jià)的,這個(gè)動(dòng)作是不是防御動(dòng)作不知道,,有防御框或者完全沒(méi)有受擊框的都可以是防御動(dòng)作,,有攻擊框的都可以是攻擊動(dòng)作,同樣的一個(gè)動(dòng)作也可以同時(shí)有攻擊框和防御框,;而必殺技的設(shè)計(jì),,也是從“基礎(chǔ)的拳腳功夫之外的一些特殊動(dòng)作”而非回合制游戲的“技能就是比較強(qiáng)大的攻擊方式”的角度出發(fā)設(shè)計(jì)的。因此在這個(gè)設(shè)計(jì)思路下,,動(dòng)作之間的切換就有更靈活的需求,,比如:

圖片

你很難定義其中那些動(dòng)作是普通攻擊。而在傳統(tǒng)的動(dòng)作游戲中,,還有這樣一個(gè)細(xì)節(jié)設(shè)定——即當(dāng)我們揮空的時(shí)候,,角色會(huì)保持“3連普通攻擊”的第一段,只有命中了,,才會(huì)進(jìn)入第二段,、第三段,這也是即時(shí)回合制游戲不好做的細(xì)節(jié)(但是動(dòng)作游戲要做到即時(shí)回合制這樣打一下就加一段是十分簡(jiǎn)單的),,下文會(huì)詳細(xì)說(shuō)到,。

圖片

(只有打中人了,才會(huì)進(jìn)入第二段連招)

而除了攻擊之外,,還有下文會(huì)專門提到的受傷動(dòng)作更是如此——是一個(gè)很典型的不同受傷動(dòng)作本當(dāng)是“不同狀態(tài)”的存在,,那假如所有的動(dòng)作都是不同“狀態(tài)”,還如何用有限狀態(tài)機(jī)(FSM),?那思路逆轉(zhuǎn)過(guò)來(lái),,是不是用狀態(tài)機(jī)來(lái)思考本身就是個(gè)錯(cuò)誤?
02 開(kāi)發(fā)和設(shè)計(jì)時(shí)的具體問(wèn)題
說(shuō)完了理論部分,,接下來(lái)我們就要實(shí)實(shí)在在的來(lái)看一下,,動(dòng)作游戲的動(dòng)作系統(tǒng)是如何開(kāi)發(fā)的了,在這里你會(huì)真切的感受到他與即時(shí)回合制游戲的根本不同,。老規(guī)矩,,我們(設(shè)計(jì)游戲,就要)從數(shù)據(jù)結(jié)構(gòu)開(kāi)始,。

NO.1

必要的數(shù)據(jù)結(jié)構(gòu)

角色身上必要的相關(guān)數(shù)據(jù)

在一個(gè)角色身上,,我們至少要有3個(gè)相關(guān)數(shù)據(jù):
當(dāng)前動(dòng)作幀(Frame):因?yàn)椤皫亲钚∵壿媶挝弧币惨驗(yàn)椤皠?dòng)作游戲每一幀世界都在變化”,因此這個(gè)角色當(dāng)前所處的“狀態(tài)”就是一個(gè)動(dòng)作幀,。除了邏輯運(yùn)算安全依賴于這個(gè)數(shù)據(jù),,渲染也會(huì)有相關(guān)的邏輯保證動(dòng)作不超過(guò)這一幀。
掌握的動(dòng)作(List<Action>):一個(gè)角色會(huì)做的所有動(dòng)作,,從基本的站立,、走路到所有的必殺技,,只要是這個(gè)角色能做的動(dòng)作,就應(yīng)該被記錄在角色身上,。由于一個(gè)角色的動(dòng)作是可以動(dòng)態(tài)增刪的,,比如在某些條件下可以學(xué)會(huì)一個(gè)新的動(dòng)作或者遺忘一個(gè)老的動(dòng)作,,所以還是使用List比較好,,不然應(yīng)該是一個(gè)array(本文中相關(guān)的內(nèi)容都是同理,使用List的地方都是因?yàn)閿?shù)據(jù)的個(gè)數(shù)本當(dāng)是動(dòng)態(tài)的,,而非固定的),。
碰撞記錄(List<HitRecord>):在當(dāng)前動(dòng)作中,我們打中過(guò)誰(shuí)需要有個(gè)記錄,,因?yàn)槊恳粠伎赡馨l(fā)生我們碰撞到(打擊了)同一個(gè)角色,,但是我們并不能每一幀都有效的攻擊,因此我們要剔除掉已經(jīng)打擊過(guò)的對(duì)象,,所以要記錄一個(gè)打擊信息,,來(lái)記住我們最近打過(guò)了誰(shuí),還有多久就能再次打中,。通常來(lái)說(shuō)這個(gè)列表在角色更換動(dòng)作的時(shí)候會(huì)被清除,。

一個(gè)動(dòng)作的數(shù)據(jù)(Action)

由于是一個(gè)動(dòng)作游戲,所以動(dòng)作數(shù)據(jù)并不會(huì)非常復(fù)雜,,他更像是一個(gè)“包裹”,,主要的作用是把一些幀打包在一起,從而解決一些策劃配置和理解的問(wèn)題,,畢竟游戲最后是需要靠人去做的,,我們不能太過(guò)程序化了,因此這個(gè)結(jié)構(gòu)的存在,,更確切的說(shuō)法,,就是一個(gè)“語(yǔ)法糖”。一個(gè)動(dòng)作數(shù)據(jù)的意義很好理解,,就是一個(gè)角色可以做的每個(gè)動(dòng)作需要都是一個(gè)動(dòng)作的數(shù)據(jù),,比如輕拳、比如起跳等,。一個(gè)動(dòng)作至少需要這些數(shù)據(jù):
動(dòng)作名(string):每個(gè)動(dòng)作都可以有一個(gè)名字,,之所以是動(dòng)作名而不是動(dòng)作id,是因?yàn)椴煌膭?dòng)作的動(dòng)作名可以完全相等,,這是允許的用法,,甚至應(yīng)當(dāng)巧妙地去運(yùn)用好。
動(dòng)作幀(List<Frame>):一個(gè)動(dòng)作是由若干個(gè)動(dòng)作幀組成的,,這些動(dòng)作幀的“自然下一幀”都會(huì)是列表的下一個(gè)動(dòng)作幀,,除了最后一個(gè)動(dòng)作幀之外,。動(dòng)作幀是一個(gè)動(dòng)作的靈魂所在,因?yàn)樵揪筒恍枰皠?dòng)作”這個(gè)概念,,只需要?jiǎng)幼鲙纯?,但是我們這里還是做了一個(gè)“語(yǔ)法糖”,事實(shí)證明,,有“動(dòng)作”概念可以讓工作復(fù)雜度級(jí)數(shù)次方的下降,。
自然的下一個(gè)動(dòng)作(Action):即這個(gè)動(dòng)作的最后一幀之后的下一個(gè)動(dòng)作的第一幀。比如打拳打完了會(huì)回到握拳站立動(dòng)作,,這非常好理解,,之所以單獨(dú)列一條,也是因?yàn)楸旧磉@就是“語(yǔ)法糖”,,所以要保持“甜味”,。
動(dòng)畫(huà)信息(string等):動(dòng)畫(huà)(animation)和動(dòng)作(action)是不一樣的東西,動(dòng)畫(huà)是美術(shù)制作的,,而動(dòng)作則是一個(gè)邏輯數(shù)據(jù),。在一個(gè)正常的動(dòng)作游戲中,同一個(gè)動(dòng)畫(huà)可以是完全不同的動(dòng)作,,但是同一個(gè)動(dòng)作不能有不同的動(dòng)畫(huà),,因?yàn)閯?dòng)作邏輯數(shù)據(jù)是嚴(yán)肅的。用“狀態(tài)機(jī)”的思路來(lái)理解,,就是“一個(gè)狀態(tài)有多個(gè)動(dòng)作(此處動(dòng)作實(shí)則為動(dòng)畫(huà))是不允許的”,。
入指令(Command[]):盡管在傳統(tǒng)的動(dòng)作游戲中,,我們都是每一幀設(shè)置指令的,,但是實(shí)際需求來(lái)看,,每個(gè)動(dòng)作有一個(gè)指令列表才是對(duì)的。這里指令使用數(shù)組的原因是一個(gè)動(dòng)作的指令未必是單一的,,甚至可以開(kāi)放給玩家配置,,比如玩家設(shè)置下前拳或者下前腳這樣的指令都可以發(fā)動(dòng)某個(gè)動(dòng)作,這是允許的,,但是要注意,,這里的指令并非“鍵盤Q鍵”“手柄三角鍵”之類的具體按鍵,他只是一個(gè)命令集,。
CancelTags(List<CancelTag>):這個(gè)動(dòng)作可以Cancel別的動(dòng)作的信息,,這通常邏輯上來(lái)說(shuō),都是跟動(dòng)作比較好的,,畢竟我們說(shuō)Cancel本身就是“一個(gè)動(dòng)作做到一半切換另外一個(gè)動(dòng)作”,,所以這“另外一個(gè)動(dòng)作”能不能是這個(gè)動(dòng)作,,就用Action.CancelTags來(lái)決定,是一個(gè)很舒服的設(shè)計(jì),。
基礎(chǔ)優(yōu)先級(jí)(int):動(dòng)作的基礎(chǔ)優(yōu)先級(jí),,因?yàn)槲覀儾还茏鍪裁礃拥挠螒颍灰婕暗絼?dòng)作切換,,一定會(huì)有當(dāng)前動(dòng)作同時(shí)可以切換到若干動(dòng)作的局面,,但實(shí)際上我們真正能切換到的只能是一個(gè)動(dòng)作,畢竟一個(gè)角色一個(gè)時(shí)刻只可能做一個(gè)動(dòng)作,,這是基礎(chǔ)的性質(zhì)無(wú)法改變,,所以就有了“從若干動(dòng)作中挑選出最合適的”這個(gè)問(wèn)題,,那么篩選動(dòng)作的最好方式是根據(jù)優(yōu)先級(jí)冒泡,,當(dāng)然這里只是一個(gè)基礎(chǔ)的優(yōu)先級(jí),,動(dòng)作游戲里可并沒(méi)有那么簡(jiǎn)單?;A(chǔ)優(yōu)先級(jí)也是用來(lái)描述動(dòng)作之間在沒(méi)有任何條件的情況下的優(yōu)先級(jí),,比如死亡動(dòng)作的基礎(chǔ)優(yōu)先級(jí)會(huì)高于其他大多動(dòng)作。
打擊信息(HitInfo):原本這個(gè)信息應(yīng)該屬于Frame,,但是由于動(dòng)作這個(gè)語(yǔ)法糖,,使得這個(gè)信息更簡(jiǎn)化的出現(xiàn)在動(dòng)作數(shù)據(jù)里面了,,這是在打中目標(biāo)之后做記錄的一個(gè)依據(jù),,也就是說(shuō)我要記錄我打中了目標(biāo)還能打多少次等內(nèi)容的。
其他:可以根據(jù)擴(kuò)展玩法來(lái)設(shè)計(jì)一些必要的屬性,,比如我們有替換技系統(tǒng),,那么技能就該有個(gè)名字好讓玩家有個(gè)“官方稱呼”方式。當(dāng)然除了這些“新增”項(xiàng)目之外,,如果我們?cè)谕粋€(gè)動(dòng)作中的每一個(gè)動(dòng)作幀都會(huì)去填寫(xiě)一樣的值的數(shù)據(jù),,也可以放在動(dòng)作里面,比如我們認(rèn)為整個(gè)動(dòng)作的“攻擊力倍率”屬性都是0.7(即怪物獵人中的動(dòng)作值的概念),,不用精細(xì)到跟幀走,,那么就在動(dòng)作層設(shè)置“攻擊力倍率”屬性就好了。

打擊信息(HitInfo)與碰撞記錄(HitRecord)

為了避免同一個(gè)動(dòng)作連續(xù)好幾幀都命中同一個(gè)目標(biāo),,造成連續(xù)傷害(很可能一秒就發(fā)生60次碰撞),,我們需要一個(gè)碰撞記錄來(lái)避免連續(xù)被命中,碰撞記錄必要的數(shù)據(jù)有:
標(biāo)(Character):這條記錄證明我當(dāng)前的動(dòng)作打中了誰(shuí),,也就是繼續(xù)保持這個(gè)動(dòng)作,,我要再碰到這個(gè)目標(biāo)的時(shí)候,就要看看這條數(shù)據(jù)允許不允許我再次打中他了,。
還剩多少幀可以再次打中(int):這是一個(gè)剩余幀數(shù),,因此每一幀自然-1,當(dāng)這個(gè)值<=0的時(shí)候,,如果“還能打中幾次”大于0,,就能再次打中目標(biāo),并且降低1次“還能打中幾次”,。
還能打中幾次(int):一般來(lái)說(shuō)一個(gè)動(dòng)作都只能打中目標(biāo)1次,,當(dāng)然也有例外,為了讓玩家爽快,,一個(gè)動(dòng)作可以允許連續(xù)命中好幾段,,配合“還剩多少幀可以再次打中”就有了這個(gè)效果,經(jīng)典的街機(jī)游戲《吞食天地2》中玩家使用草薙劍砍人,,就會(huì)有一刀3段傷害的設(shè)定,。
為了對(duì)應(yīng)產(chǎn)生碰撞記錄,我們?cè)趧?dòng)作里面會(huì)有一個(gè)打擊信息,,這個(gè)打擊信息是用來(lái)“改寫(xiě)”碰撞記錄的規(guī)則,,它包含的必要信息有:
同一目標(biāo)命中次數(shù)(int):當(dāng)創(chuàng)建(而非修改)一個(gè)目標(biāo)(character)所在的HitRecord的時(shí)候,“還能打中幾次”就會(huì)等于這個(gè)值,。
命中間隔幀數(shù)(int):這是為HitRecord的“還剩多少幀可以再次打中”賦值的,。

動(dòng)作幀的數(shù)據(jù)(Frame)

動(dòng)作幀是動(dòng)作游戲的核心數(shù)據(jù),,盡管我們有了“動(dòng)作”這層“語(yǔ)法糖”,,但是邏輯上“動(dòng)作幀”依然還是動(dòng)作游戲中角色的“動(dòng)作單位”,,因此在角色屬性中“當(dāng)前動(dòng)作幀”依然是這樣一個(gè)結(jié)構(gòu)的數(shù)據(jù)。動(dòng)作幀需要的關(guān)鍵數(shù)據(jù)有:
動(dòng)畫(huà)關(guān)鍵幀(float):拿Unity來(lái)舉例,,動(dòng)畫(huà)是在Update上走的,,用的是一個(gè)deltaTime的方式(即上面說(shuō)到的每一個(gè)Update的Tick去算插值),由于動(dòng)畫(huà)是給玩家看到的最基本也是唯一的信息,,所以動(dòng)畫(huà)表現(xiàn)出來(lái)的當(dāng)前狀態(tài)是十分重要的,,而動(dòng)畫(huà)因?yàn)槭窃趗pdate,與在FixedUpdate上運(yùn)行的邏輯可以看做是2個(gè)不同線程上(盡管unity實(shí)現(xiàn)并不是2個(gè)不同線程這樣的),,所以存在一個(gè)“同步”問(wèn)題,,也就是說(shuō),邏輯需要告訴動(dòng)畫(huà),,你最多可以播放到哪兒,,如果我邏輯還沒(méi)有去下一幀,那么你動(dòng)畫(huà)播放到這里就應(yīng)該“卡住不動(dòng)”了,。
循環(huán)幀數(shù)(int):一個(gè)動(dòng)作幀的下一幀直接是自己這一幀的次數(shù),,這個(gè)循環(huán)幀數(shù)通常都是1,,但是格斗游戲中的受傷動(dòng)作,,是動(dòng)態(tài)算出來(lái)的。這正是《街霸》這些游戲中玩家可以看到一些+6,、-30之類的數(shù)據(jù)的來(lái)源之一,,正因?yàn)槭軅麆?dòng)作中某些Frame的循環(huán)次數(shù)增多了,所以動(dòng)作“變得更慢了”或者“硬直更久了”,,以至于這個(gè)(玩家理解的)“加減幀”數(shù)據(jù)發(fā)生了變化,。
Cancel信息(List<CancelData>):當(dāng)角色處于這幀的時(shí)候,允許被那些動(dòng)作所Cancel,,這是與動(dòng)作中的CancelTag對(duì)應(yīng)的數(shù)據(jù),,在后面會(huì)詳細(xì)說(shuō)到。
身體碰撞框(Rect[]\Box[]):2D游戲中通常是Rect(便于aabb計(jì)算提高性能),,3D游戲中是Box,,這是用于和地形做碰撞的。
攻擊框(AttackHitBox[]):角色的攻擊框,,在每一幀,,角色的攻擊框數(shù)量、大小等等都是可以完全不同的,,但是這一幀一定有若干個(gè)(或者0個(gè)),。
擊框(HitBox[]):角色的受擊框,每一幀也會(huì)有0或者若干個(gè),,任何受擊框遭遇到任何攻擊框都可以看做是“碰到了”,,這個(gè)概念會(huì)在后面詳細(xì)說(shuō)到,。
下一幀(Frame):當(dāng)完成了循環(huán)次數(shù)之后,這個(gè)Frame的下一個(gè)Frame是哪個(gè),,畢竟我們需要?jiǎng)幼骼^續(xù)播放下去的,,只是這個(gè)Frame僅僅是一個(gè)“候選人”,他還要跟Cancel的內(nèi)容去競(jìng)爭(zhēng)的,,也就是有Cancel的動(dòng)作的時(shí)候,,這個(gè)“下一幀”就沒(méi)必要加入到“候選人”列表中去了?!昂蜻x人”列表是個(gè)什么概念,,會(huì)在后面的“動(dòng)作切換的邏輯和配置”一章中詳細(xì)講解。
游戲玩法相關(guān)數(shù)據(jù):玩法相關(guān)的數(shù)據(jù),,包括前面舉例說(shuō)的“攻擊力倍率”等,,都是看情況放在Frame或者Action中的,甚至精細(xì)一點(diǎn)還會(huì)放在攻擊框里面,,我們這里就按照放在攻擊框里面來(lái)做,,所以會(huì)在下一章的“攻擊框與受擊框”中詳細(xì)說(shuō)。

攻擊框與受擊框(HitBox)

在動(dòng)作游戲的實(shí)際開(kāi)發(fā)中,,只有攻擊框和受擊框2種框,,他們有共同點(diǎn),也可以都派生于“框”(如果你很喜歡oop的話),,也有各自獨(dú)有的東西,。當(dāng)然這里要強(qiáng)調(diào)一個(gè)關(guān)鍵,所謂格斗游戲中的“抓取框”和“被抓框”,、“不意打”“鎖骨割”對(duì)下段,、動(dòng)作游戲常見(jiàn)的“防御框”“格擋框”“JustDodge框”等,都只是一個(gè)人類的邏輯概念,,事實(shí)上他們?cè)陂_(kāi)發(fā)中,,只是配置了不同的參數(shù)所致的。那么我們接下來(lái)就看看“框”共有的參數(shù):
框體(Rect\Box):這個(gè)框體相對(duì)于角色坐標(biāo)的偏移量,,2D中通常都是Rect,,3D通常都是Box,當(dāng)然你也可以選擇自己喜歡的,,比如用圓形也沒(méi)什么不行,,具體還是看游戲設(shè)計(jì)如何。
自身動(dòng)作變化信息(ActionChangeInfo):當(dāng)這個(gè)動(dòng)作的優(yōu)先級(jí)高于對(duì)手框(攻擊框的對(duì)手框是受擊框,,反之,,受擊框的對(duì)手框也一定是攻擊框)的時(shí)候,那么我自己會(huì)如何改變動(dòng)作,就取決于這個(gè)信息了,;如果對(duì)手動(dòng)作的優(yōu)先級(jí)更高,,那么我就會(huì)變成對(duì)手動(dòng)作的“對(duì)手動(dòng)作變化信息”指向的動(dòng)作。這看起來(lái)雖然有點(diǎn)繞,,但事實(shí)就是這樣工作的才正確,。
對(duì)手動(dòng)作變化信息(ActionChangeInfo):對(duì)應(yīng)“自身動(dòng)作變化信息”,如果我這個(gè)框的優(yōu)先級(jí)更高的時(shí)候,,對(duì)手的動(dòng)作變化依賴于這個(gè)數(shù)據(jù),。
優(yōu)先級(jí)(int):A角色與B角色的一次碰撞中,很可能會(huì)產(chǎn)生若干個(gè)A的攻擊框碰到B的受擊框的信息,,當(dāng)然也可能同時(shí)有很多B的攻擊框碰到A的受擊框的信息,,我們將一個(gè)角色的攻擊框碰到其他人受擊框(比如A的攻擊框碰到B的受擊框)的信息列表冒泡,先根據(jù)攻擊框的優(yōu)先級(jí)冒泡,,攻擊框優(yōu)先級(jí)最高的那個(gè)可能同時(shí)還碰到了很多受擊框,,此時(shí)冒泡出受擊框優(yōu)先級(jí)最高的,就是這次碰撞的“有效碰撞信息(雙方的框)”,。通過(guò)這兩個(gè)框(攻擊方優(yōu)先級(jí)最高的框vs它所碰到的受擊方受擊框中優(yōu)先級(jí)最高的)的優(yōu)先級(jí)對(duì)比,,得出如果攻擊框的優(yōu)先級(jí)>(而非>=)受擊框的優(yōu)先級(jí),則采用攻擊方的“動(dòng)作變化信息”(自身和對(duì)手那兩個(gè)),,否則采用受擊方的,。
對(duì)口(組)標(biāo)志(string[]):并不是每個(gè)攻擊框?qū)γ總€(gè)受擊框都有效的,比如攻擊框?qū)Α氨蛔ト】颉?,只有雙方標(biāo)志有共同的值的時(shí)候,,才可能碰上。當(dāng)然我們也因此可以定義出一些標(biāo)志碰到另一些標(biāo)志可以忽略優(yōu)先級(jí)來(lái)讓攻擊框一定主導(dǎo)“動(dòng)作變化”(鎖骨割等),。
而攻擊框和受擊框各自還特有一些屬性,他們都是根據(jù)游戲內(nèi)容設(shè)定來(lái)的,,攻擊框特有的參數(shù)常見(jiàn)的有:
攻擊力倍率(int):這個(gè)攻擊框碰到受擊框的時(shí)候,,攻擊力怎么算。
卡幀(int/int):攻擊有效時(shí),,雙方進(jìn)行卡幀的時(shí)間,,攻擊方和受擊方卡幀時(shí)間不同,具體會(huì)在下文描述,。
硬直(int):受擊方除了卡幀,,還會(huì)硬直,也會(huì)在下文中進(jìn)一步詳細(xì)描述,。
吹飛力(int):這個(gè)攻擊框有效(優(yōu)先極高)的時(shí)候會(huì)把目標(biāo)直接擊飛多少,,對(duì)抗對(duì)方的“沉重度”,而對(duì)方優(yōu)先極高的時(shí)候,則對(duì)抗穩(wěn)固度,。
擊退力(int):與吹飛力相似,,只是作用在水平坐標(biāo)而非垂直坐標(biāo)變化上。
硬直幀(int):同樣是對(duì)抗穩(wěn)固力和沉重度,,是對(duì)方動(dòng)作硬直的加幀(這個(gè)規(guī)則得策劃定義,,通常來(lái)說(shuō),是一個(gè)動(dòng)作中第一個(gè)“循環(huán)幀數(shù)”>1的幀來(lái)設(shè)定更大的“循環(huán)幀數(shù)”值),。
受擊框特有的參數(shù)常見(jiàn)的有:
防御力(int):這個(gè)框受擊時(shí)候的攻擊減傷能力,。
硬直抵抗(int):對(duì)抗攻擊框的硬直屬性用的,具體算法各家游戲不同,,可以根據(jù)自己的游戲需要來(lái)自行設(shè)計(jì)公式,。
穩(wěn)固力(int):當(dāng)這個(gè)框優(yōu)先極高的時(shí)候,對(duì)抗硬直幀,、吹飛力,、擊退力的參數(shù)。
沉重度(int):當(dāng)攻擊框優(yōu)先級(jí)高的時(shí)候,,對(duì)抗硬直幀,、吹飛力、擊退力的參數(shù),。
到這里,,我們不難看出——所謂的“格擋框”,不過(guò)是一個(gè)優(yōu)先級(jí)高,、穩(wěn)固力高的受擊框而已,,并不需要特殊處理或者說(shuō)特別定義一種叫做“格擋框”的東西。

動(dòng)作變化信息(ActionChangeInfo)

動(dòng)作變化信息是用來(lái)在碰撞發(fā)生后,,決定雙方動(dòng)作變化的信息,,這個(gè)動(dòng)作變化是被加入到“候選人”中的,也就是說(shuō)他未必最終一定會(huì)變成這個(gè)動(dòng)作——你可以想像一下,,我一刀砍出出去同時(shí)命中了3個(gè)目標(biāo),,2個(gè)目標(biāo)光頭被砍,一個(gè)帶著超級(jí)鈦合金頭盔,,因此我彈刀——前兩個(gè)都是我的優(yōu)先極高,,所以我保持動(dòng)作了,最后一個(gè)是因?yàn)樗膬?yōu)先極高,,所以我得聽(tīng)他的切換到彈刀動(dòng)作,。這就是這個(gè)動(dòng)作變化信息要用的地方,它的核心數(shù)據(jù)有:
變化類型(枚舉):保持現(xiàn)在的動(dòng)作,,或者變化到某個(gè)指定名稱的動(dòng)作,。
變化為動(dòng)作(string):如果類型是變化為指定名稱的動(dòng)作,那么如果角色存在名字符合這個(gè)的動(dòng)作(可能會(huì)有好幾個(gè)同名的動(dòng)作,每一個(gè)都要進(jìn)行一次判斷),,就會(huì)判斷是否被允許Cancel(具體會(huì)在Cancel信息一章說(shuō)到),,如果允許就會(huì)被加入候選列表(這里也是動(dòng)作名稱秒用的關(guān)鍵點(diǎn)之一)。
起始幀(Frame):如果變化為那個(gè)動(dòng)作起始幀是第幾幀(指向某個(gè)Frame),。
臨時(shí)開(kāi)啟CancelTag信息(List<(CancelTag, int)>):變化動(dòng)作后,,臨時(shí)開(kāi)啟若干幀(int)的CancelTag,這里是做到“3連普通攻擊第一下命中了才會(huì)出第二段,,否則保持第一段”的關(guān)鍵,,而《街霸6》中很多的連招,也都是通過(guò)這個(gè)來(lái)實(shí)現(xiàn)的,。值得注意的是,,這是在動(dòng)作切換之后才臨時(shí)開(kāi)啟的,這個(gè)時(shí)序不能反了(盡管看起來(lái)反了也沒(méi)事兒),。
到這里我們不難看出,,一個(gè)動(dòng)作如果前幾幀的受擊框優(yōu)先級(jí)很高,且“自身動(dòng)作變化”為一個(gè)可以快速反擊的動(dòng)作,、之后幾幀變成重重的格擋住的動(dòng)作,,就有了“Just Block”的設(shè)定了,也是完全不用特殊處理什么“防御動(dòng)作開(kāi)始后0.1秒受到攻擊”,,不需要特殊寫(xiě)個(gè)if else,。

Cancel信息(CancelTag\CancelData)

CancelTag和CancelData是決定2個(gè)動(dòng)作切換的一個(gè)關(guān)鍵信息,他們之間的關(guān)系就像是鎖跟鑰匙的關(guān)系,,有一種對(duì)應(yīng)關(guān)系,,并且因?yàn)檫@種對(duì)應(yīng)關(guān)系產(chǎn)生聯(lián)動(dòng)。在一個(gè)動(dòng)作的動(dòng)作幀本身有一些CancelTag,,他們就像是鎖孔一樣,,本身沒(méi)有直接的作用,但是因?yàn)槠渌麆?dòng)作有CancelData,,這些有CancelData的動(dòng)作就仿佛鑰匙能開(kāi)鎖一般的,,和這個(gè)動(dòng)作幀產(chǎn)生關(guān)聯(lián),最后可以形成“動(dòng)作的切換”,。所以動(dòng)作游戲的“動(dòng)作切換”的關(guān)鍵所在,就是這個(gè)CancelTag和CancelData的配置,。CancelTag在每一幀的信息上,,他必須要有這樣的數(shù)據(jù):
Tag(string):這是一個(gè)和CancelData的Tag對(duì)應(yīng)的東西,只有當(dāng)CancelData的Tag中包含這個(gè)CancelTag的Tag,,他們之間才會(huì)有Cancel關(guān)系,,也就是那個(gè)動(dòng)作可以Cancel掉當(dāng)前幀。
優(yōu)先級(jí)修正(int):如果動(dòng)作可以在此幀進(jìn)行Cancel,那么那個(gè)動(dòng)作的優(yōu)先級(jí)會(huì)被加上這個(gè)值進(jìn)行修正,。并不是每個(gè)動(dòng)作的優(yōu)先級(jí)總是一樣的,,比如在重拳之后,完全允許重腳的優(yōu)先級(jí)是最高的,,以形成一個(gè)獨(dú)特的連招,,因此我們會(huì)需要臨時(shí)調(diào)整一些動(dòng)作的優(yōu)先級(jí),以確保他能在這個(gè)環(huán)境下優(yōu)先被釋放,。
現(xiàn)在激活(bool):我們當(dāng)然允許策劃事先配置好所有的cancel情況,,但是一些cancel情況可以暫時(shí)不激活,只有當(dāng)發(fā)生碰撞(ActionChangeInfo中)激活,,或者走一些其他的玩法,,比如通過(guò)角色喝了在游戲中啤酒之后激活他們,這可以看游戲具體設(shè)計(jì)以及實(shí)現(xiàn)方式需要不需要,。
相對(duì)于CancelTag,,動(dòng)作的CancelData需要的信息主要有:
Tag(string[]):和CancelTag中的Tag對(duì)應(yīng),之所以是數(shù)組,,是因?yàn)橐粋€(gè)動(dòng)作可以Cancel的動(dòng)作幀可能有很多種,,這具體看策劃設(shè)計(jì),但是至少得有1種,,不然這個(gè)動(dòng)作要這個(gè)信息就沒(méi)用了,。
優(yōu)先級(jí)修正(int):當(dāng)這個(gè)動(dòng)作走這個(gè)CancelData去Cancel別的動(dòng)作的時(shí)候,動(dòng)作的優(yōu)先級(jí)除了加上CancelTag的優(yōu)先級(jí),,還要加上CancelData的優(yōu)先級(jí),,進(jìn)行進(jìn)一步精確地調(diào)整,既然是int,,自然是可加可減的,,讓策劃有更靈活的用法。
指令變化(Command[]\Command[]):一些動(dòng)作在某些條件下Cancel其他動(dòng)作,,可以有更多或者更少的指令,,以便更方便玩家使出來(lái)或者要求玩家更精確的操作才能使出來(lái),這其實(shí)是一個(gè)手感調(diào)整的數(shù)據(jù),,但是既然我們做動(dòng)作游戲,,跟大菠蘿最大的區(qū)別就是手感十分重要對(duì)吧。
起始幀(int):當(dāng)這個(gè)動(dòng)作Cancel掉之前的動(dòng)作之后,,是從第幾幀開(kāi)始的,。
臨時(shí)開(kāi)啟的CancelTag等信息:實(shí)際上這里想說(shuō)的是還可以定制很多數(shù)據(jù),主要看游戲設(shè)計(jì)的細(xì)節(jié)需要了,。這里之所以提這個(gè),,是因?yàn)檫@是一個(gè)常見(jiàn)的需求,,但是雖然常見(jiàn),要駕馭好又很難,,所以只是提一嘴——如果是走這個(gè)CancelData去Cancel別的動(dòng)作的話,,可以臨時(shí)開(kāi)啟或者關(guān)閉一些這個(gè)動(dòng)作下的一些幀的CancelTag,來(lái)調(diào)整連招派生關(guān)系和手感,,這是一個(gè)細(xì)膩活,,但是做好確實(shí)讓玩家體驗(yàn)會(huì)好很多,只是現(xiàn)代商業(yè)化游戲花這個(gè)時(shí)間和心思從性價(jià)比來(lái)說(shuō)可能并不值得,,畢竟你至少需要有很好的游戲策劃才行,。
到這里,不得不在提醒一句——每個(gè)動(dòng)作幀的CancelTag都是一個(gè)數(shù)組,、每一個(gè)動(dòng)作的CancelData也是一個(gè)數(shù)組,,所以他們的關(guān)系可以并不是簡(jiǎn)單的一一對(duì)應(yīng)的,可以多對(duì)多,,善加利用,,就可以做出靈便性極好的連招來(lái),根據(jù)自己喜好和感知打出行云流水的連招來(lái),,對(duì)于玩家來(lái)說(shuō)是一件十分爽快的事情,。

輸入指令(Command)

這是一個(gè)非常“搞”的數(shù)據(jù),,實(shí)際開(kāi)發(fā)交流中,,我發(fā)現(xiàn)和不少團(tuán)隊(duì)的人交流這個(gè)的時(shí)候是存在一定理解障礙的,值得單獨(dú)寫(xiě)一下,。首先我們還是說(shuō)他的數(shù)據(jù)有哪些核心的:
指令(string):這里的指令包括且不限于“前進(jìn)”“蹲下”等指令,,他們雖然(從玩家角度)看起來(lái)和按鈕是一一對(duì)應(yīng)的,但實(shí)際上對(duì)應(yīng)關(guān)系也并非這么的絕對(duì),,所以是需要把來(lái)自設(shè)備的輸入(比如unity中的Input.GetKeyDown()等)進(jìn)行“翻譯”,,轉(zhuǎn)化為這個(gè),而翻譯的過(guò)程依賴于Config中(一些游戲會(huì)開(kāi)放給玩家的輸入設(shè)置)的配置,。這里會(huì)有一些弱耦合,,但關(guān)系不大, 比如在街霸中,,我們的角色在左側(cè),,按下方向右,得到的是“前進(jìn)”,,角色在左側(cè),,按下右就是“后退”了。
按下(bool):是按下還是抬起,,這是標(biāo)準(zhǔn)的輸入都有的2個(gè)狀態(tài),,這很好理解,一般設(shè)備里只有down和up,,而click和雙擊,、holding這些的都是“糖”,通常需要自己實(shí)現(xiàn),,通過(guò)時(shí)間戳判定,。
時(shí)間戳(int/float等取決于設(shè)備和環(huán)境):按下的時(shí)間戳,根據(jù)系統(tǒng)(引擎)給你的數(shù)據(jù)記錄就行了,,只要統(tǒng)一單位就沒(méi)問(wèn)題,,也可以用邏輯幀,第幾幀得到的這個(gè)輸入也可以,,他的作用是查詢的時(shí)候用,。在一些十分講究輸入的游戲(大多為格斗游戲,比如《街霸》)中,,每幀的CancelTag里甚至有“檢查指令時(shí)間范圍”,,即只有符合這個(gè)時(shí)間范圍內(nèi)的輸入才是有效的,所以怎么利用這個(gè)記錄做手感,,是一件細(xì)膩活,,他也會(huì)影響到連續(xù)出招的手感。
這里最“搞”的地方,,就是在游戲中,,并不是和軟件一樣的“按鍵觸發(fā)”方式,當(dāng)然如果是回合制游戲,,比如即時(shí)回合制的魂系游戲,,“按鍵觸發(fā)”是沒(méi)問(wèn)題的。但是在動(dòng)作游戲中,,是個(gè)每個(gè)Player(player不一定是玩家操作的,,這是一個(gè)游戲?qū)S忻~,特指“幾號(hào)玩家”,,操作“幾號(hào)玩家”的未必是真人,,也可以是ai)的輸入都有一個(gè)List<Command>的,每次輸入會(huì)添加入這個(gè)List,,定時(shí)也會(huì)清理,。而每一幀實(shí)際都是檢測(cè)這個(gè)列表來(lái)決定是否發(fā)生動(dòng)作的,這個(gè)細(xì)節(jié)具體在下一章“動(dòng)作切換的邏輯”中會(huì)詳細(xì)提及,。但是無(wú)論如何請(qǐng)記住一個(gè)要點(diǎn)——他不是“按鍵觸發(fā)”,,而是“每一幀檢查”的用法,要不別說(shuō)做不了搓招,,就是手感都會(huì)有些許僵硬,,當(dāng)然現(xiàn)代玩家可能感覺(jué)得到說(shuō)不清楚,,也就只能“不在乎”了。

NO.2

動(dòng)作切換的邏輯和配置

說(shuō)完數(shù)據(jù)結(jié)構(gòu)之后,,就是我們的核心邏輯,,也就是這個(gè)“動(dòng)作游戲的動(dòng)作系統(tǒng)”最關(guān)鍵的內(nèi)容——?jiǎng)幼髑袚Q的邏輯了。在這里,,我們還是要提一句“動(dòng)作游戲每一幀世界都是變化的”,,因此,我們首先要把視角定格在“每一幀”來(lái)看這個(gè)問(wèn)題,,那么在每一幀,,每個(gè)角色發(fā)生了什么呢?他的流程是這樣的:

圖片


在這個(gè)流程里面有幾個(gè)細(xì)節(jié):
●我能否切換到一個(gè)動(dòng)作的某一幀可以完全依賴于Cancel關(guān)系:我們可以看到實(shí)際上我們可以進(jìn)入下一個(gè)動(dòng)作候選列表的動(dòng)作,,大多是通過(guò)Cancel關(guān)系篩選出來(lái)的,,因?yàn)槲視?huì)的動(dòng)作的CancelData和我當(dāng)前幀的CancelTag能對(duì)上,這個(gè)動(dòng)作才有可能被加入到Cancel列表中,,當(dāng)然一般“主動(dòng)觸發(fā)”的,,但是受傷動(dòng)作,依然也可以走這個(gè)流程,,即外部系統(tǒng)告訴我要切換到受傷動(dòng)作,,相當(dāng)于增加了一個(gè)Command到CommandList,這時(shí)候我的Cancel信息里面當(dāng)前幀有3種受傷動(dòng)作,,但是因?yàn)閏ommand對(duì)應(yīng)上和優(yōu)先級(jí)篩選,,最后選出了一個(gè)“最合適當(dāng)前情況”的受傷動(dòng)作。
●Command是一個(gè)List緩存在那里,,所以才有了“提前搓招”和“模糊輸入”的可能性:就如流程里面所示,,因?yàn)檫@個(gè)動(dòng)作在我的Cancel列表中存在,所以這個(gè)動(dòng)作可以Cancel我的當(dāng)前幀,,所以我才會(huì)去檢查他有沒(méi)有可能成為我的下一個(gè)動(dòng)作,,而這里的“有沒(méi)有可能”主要看的就是Command是否發(fā)生,而Command是否發(fā)生,,則是去看CommandList,,比如當(dāng)前幀,可以被輕拳升龍拳Cancel,,于是我就回去查詢CommandList內(nèi),,最近有沒(méi)有前進(jìn)按下、蹲下按下,、前進(jìn)按下,、輕拳抬起這個(gè)隊(duì)列,即使這個(gè)隊(duì)列中有許多穿插,,比如在列表里按照輸入時(shí)間順序是:【前進(jìn)按下】,、輕腳按下,、輕腳抬起、【蹲下按下】,、前進(jìn)抬起,、【前進(jìn)按下】、中拳按下,、【輕拳按下】——只要在這個(gè)順序中,我們能匹配到對(duì)應(yīng)的指令,,就可以認(rèn)為這個(gè)動(dòng)作是可以加入到“候選列表”的,,當(dāng)然我們可以根據(jù)這個(gè)順序中的位置設(shè)計(jì)一個(gè)“親和度”來(lái)修改這個(gè)動(dòng)作Cancel時(shí)候的優(yōu)先級(jí),進(jìn)行增加或者減少,,以做到更合適的手感,,比如這次輸入的“親和度”就遠(yuǎn)不如【前進(jìn)按下】、前進(jìn)抬起,、【蹲下按下】,、【前進(jìn)按下】、前進(jìn)抬起,、【輕拳按下】來(lái)的高對(duì)吧,。
●所以《怪物獵人》中斬斧的斧形態(tài)和劍形態(tài)需要2個(gè)“狀態(tài)”嗎?如果按照魂系玩家的理解,,應(yīng)該有個(gè)狀態(tài)來(lái)證明我現(xiàn)在是用劍還是用斧頭,,但實(shí)際上根本不需要,因?yàn)橐粋€(gè)“斧頭轉(zhuǎn)劍斬”的動(dòng)作,,自然地下一個(gè)動(dòng)作就是“劍形態(tài)站立”動(dòng)作,,而這個(gè)動(dòng)作可以Cancel“斧形態(tài)站立”動(dòng)作,就這樣一個(gè)動(dòng)作的“前后關(guān)系”就自然地出現(xiàn)了玩家肉眼看見(jiàn)的“狀態(tài)”了,,但實(shí)際實(shí)現(xiàn)的時(shí)候,,壓根就沒(méi)有去做“追加一個(gè)狀態(tài)”的特殊處理。

NO.3

如何用UE的Montage或者Unity的Animator做動(dòng)作游戲

這是一個(gè)十分現(xiàn)實(shí)的問(wèn)題——畢竟我們絕大多數(shù)團(tuán)隊(duì)必須依賴于Unity或者UE才能開(kāi)發(fā)游戲,,那么如果我們要用Unity和UE開(kāi)發(fā)游戲,。我們知道Unity里主流的對(duì)于動(dòng)畫(huà)處理的是Animator,他是一個(gè)動(dòng)畫(huà)狀態(tài)機(jī),;而UE里面使用的則是角色的Animation Blueprint去調(diào)用BlendSpace和Montage來(lái)做到類似Unity的Animator對(duì)于Blendtree和State的管理,。這些做法似乎和剛才說(shuō)的動(dòng)作游戲是背道而馳的?那如何使用這些引擎來(lái)開(kāi)發(fā)動(dòng)作游戲呢,?
首先我們要明確一點(diǎn),,就是我們反復(fù)強(qiáng)調(diào)的——?jiǎng)赢?huà)(Animation)和動(dòng)作(Action)是兩回事兒,動(dòng)畫(huà)是動(dòng)作的一個(gè)屬性,,一個(gè)動(dòng)作肯定有一個(gè)動(dòng)畫(huà),,但是同一個(gè)動(dòng)畫(huà),,可以是多個(gè)動(dòng)作的動(dòng)畫(huà)屬性的的值。簡(jiǎn)單地說(shuō)actionA.animation = AnimationA,,acitonB.animation也可以等于AnimationA,。
Unity的Animator,只是一個(gè)把Animation串聯(lián)起來(lái)的東西,,我們使用它的最重要的價(jià)值就是動(dòng)作融合的編輯器,;UE的AnimBP(Animation Blueprint的簡(jiǎn)稱,下同)也是干這個(gè)的,,而UE的Blendspace和Unity的Blendtree也都是動(dòng)畫(huà)融合工具,,UE獨(dú)有的Montage則是把一個(gè)動(dòng)畫(huà)的Timeline(邏輯的Timeline)拿出來(lái),允許定義一些事件(AnimNotify和AnimNotifyState),,他也是一個(gè)編輯器作用,。

圖片


就拿unity舉例,我們可以定義一個(gè)角色的GameObject下用的Animator用的是哪個(gè)具體的Animator,,這就是定義了角色所有的動(dòng)畫(huà)而已,,而這個(gè)Animator中所有的Param,也就是那些Trigger,、bool等東西,,都只是“操控動(dòng)畫(huà)”播放的參數(shù)——這也是Animator存在的本意,我們使用它的時(shí)候,,調(diào)用這些SetTrigger函數(shù)的目的是制作動(dòng)畫(huà)之間的跳轉(zhuǎn),,而這些跳轉(zhuǎn)無(wú)非是吃到了動(dòng)作融合而已。但是誰(shuí)去調(diào)用這個(gè)Animator.SetTrigger之類的函數(shù),?就是我們說(shuō)的“動(dòng)作游戲的動(dòng)作切換系統(tǒng)”,,在動(dòng)作切換發(fā)生的時(shí)候,我們根據(jù)Frame信息中的動(dòng)畫(huà)信息(可以是set那些trigger等的組合),,來(lái)對(duì)Animator進(jìn)行操作就可以了,。
而UE提供的Montage的編輯,我們可以把AnimNotify和AnimNotifyState,,看做是“關(guān)鍵幀”的編輯,,也就是我們可以拉一段AnimNotifyState來(lái)作為CancelTag的編輯,這樣策劃可以更可視化的去編輯,,而這個(gè)AnimNotifyState是派生自AnimNotifyState的一個(gè)類,,比如就叫CancelTag。
因此,,我們?cè)谑褂肬nity和UE做動(dòng)作游戲的時(shí)候,,最重要的是一點(diǎn)——就是我們要調(diào)整心態(tài),并不是說(shuō)我們直接用Animator或者AnimBP去做角色的動(dòng)作狀態(tài)機(jī),他們只是動(dòng)畫(huà)管理器,,這里所謂的狀態(tài),,也不是FSM的“狀態(tài)”。我們使用這些只是當(dāng)做工具,,和“動(dòng)畫(huà)驅(qū)動(dòng)器”,,只要調(diào)整好這個(gè)心態(tài)就能很好的使用UE和Unity開(kāi)發(fā)動(dòng)作游戲了(當(dāng)然,如果用UE開(kāi)發(fā)動(dòng)作游戲,,你還得克服一下UE的那些底層玩法邏輯代碼帶來(lái)的諸多麻煩就是了),。

NO.4

挨打了該做哪種受傷動(dòng)作?

挨打動(dòng)作這個(gè)問(wèn)題,,其實(shí)是一個(gè)很經(jīng)典的游戲開(kāi)發(fā)問(wèn)題,,動(dòng)作游戲的挨打動(dòng)作問(wèn)題,遠(yuǎn)比非動(dòng)作游戲來(lái)得重要,,畢竟動(dòng)作游戲?qū)τ谕婕襾?lái)說(shuō),每個(gè)動(dòng)作是什么都是很重要的事情,。
在絕大多數(shù)動(dòng)態(tài)的(即時(shí)制)游戲中,,受傷動(dòng)作是一個(gè)權(quán)重非常低的動(dòng)作,因?yàn)槭軅瞬荒艽驍嘟巧男袆?dòng),,比如在《魔獸世界》里面,,我一個(gè)法師在讀條,雖然受到來(lái)自別人的普通攻擊,,會(huì)有進(jìn)度條被延緩之類的邏輯效果,,但是這并不會(huì)因?yàn)檎f(shuō)我做了一個(gè)受傷動(dòng)作,動(dòng)作變了,,就得重新讀條了,。所以一般在這樣的即時(shí)回合制游戲中,由于要做別的動(dòng)作,,就會(huì)放棄播放受傷動(dòng)作,,受傷動(dòng)作只是一個(gè)表演,只有在“空閑”的時(shí)候才會(huì)播放,,比如diablo4中野蠻人開(kāi)始使用先祖之錘了,,無(wú)論周圍多少敵人在打他,他都一定會(huì)做完錘下去的動(dòng)作,,而不會(huì)播放受傷動(dòng)作,。

圖片

(只要我在做動(dòng)作,那么敵人的“普通攻擊”就不會(huì)讓我做受傷動(dòng)作來(lái)打斷當(dāng)前動(dòng)作)


而當(dāng)我們要把一個(gè)即時(shí)回合制游戲的受傷動(dòng)作重要級(jí)抬上來(lái)的時(shí)候,,問(wèn)題就暴露了——由于即時(shí)回合游戲的邏輯上一個(gè)動(dòng)作是一個(gè)回合,,因此當(dāng)受傷這個(gè)動(dòng)作成為一個(gè)回合,并且在即時(shí)環(huán)境下,他的回合時(shí)長(zhǎng)屬性就成了一個(gè)尷尬的事情——因?yàn)槭軅麆?dòng)作是一個(gè)回合,,他會(huì)打斷之前正在做的動(dòng)作(回合),,比如我正在攻擊動(dòng)作,由于是即時(shí)回合制,,世界不是每一幀都在變化,,而是我這個(gè)動(dòng)作到了“攻擊有效幀”的時(shí)候才會(huì)產(chǎn)生傷害等效果,而攻擊有效幀是由box碰撞得來(lái)的,。因此,,很有可能發(fā)生我正在攻擊動(dòng)作,但是碰撞還未發(fā)生(也就是玩家俗稱的“前搖”),,即有效傷害幀還沒(méi)到,,我就變成了受傷(開(kāi)始了沒(méi)有攻擊判定的新回合),而當(dāng)受傷動(dòng)作結(jié)束我再次攻擊,,由于受傷本身有時(shí)長(zhǎng),,導(dǎo)致對(duì)方的進(jìn)攻依然比我快,所以我又挨打又受傷了,,那么這樣一來(lái),,我永遠(yuǎn)也沒(méi)法比對(duì)方先出手,幾乎是沒(méi)法還手的——這是一個(gè)即時(shí)回合制游戲經(jīng)典問(wèn)題,,所以魂系等游戲里面采取了玩家一側(cè)用能量條限制連續(xù)進(jìn)攻,、AI一側(cè)通過(guò)AI腳本和動(dòng)作大多直接擊飛擊倒來(lái)避免這樣的情況發(fā)生。

圖片

圖片

因此,當(dāng)我們真正動(dòng)手開(kāi)始做的時(shí)候——因?yàn)橛螒蛞涞?,就不是做一個(gè)簡(jiǎn)單的對(duì)空氣或者木樁子張牙舞爪的demo了,,所以這些細(xì)節(jié)都會(huì)被提上日程,這時(shí)候就會(huì)發(fā)現(xiàn),,其實(shí)受擊動(dòng)作是一個(gè)十分棘手的問(wèn)題,,尤其是我們用了即時(shí)回合制游戲概念的“狀態(tài)機(jī)(FSM)”來(lái)開(kāi)發(fā)的時(shí)候,,魂系游戲中那些讓人并不舒服的設(shè)定就成了不得不考慮的“補(bǔ)丁”了,至少他沒(méi)讓問(wèn)題嚴(yán)重化,。
那么動(dòng)作游戲的受擊動(dòng)作咋做,?我們要從這些細(xì)節(jié)問(wèn)題出發(fā)來(lái)做:

問(wèn)題一:下一個(gè)動(dòng)作是哪個(gè)?

這并不是一個(gè)簡(jiǎn)單到“我有一個(gè)角色8方向受擊的動(dòng)作,只要做一個(gè)blendtree,,把受擊的方向作為參數(shù)就好了”的問(wèn)題,。如果我們用非動(dòng)作游戲的概念來(lái)思考這個(gè)問(wèn)題,可能會(huì)想到的是——受傷之后要有個(gè)受傷狀態(tài),,想的再仔細(xì)一定,這些就是不同情況下受傷動(dòng)作不同,,給個(gè)if else就解決問(wèn)題了,。
但是動(dòng)作游戲的受擊動(dòng)作,,未必是受傷動(dòng)作,,或者說(shuō)精細(xì)到哪個(gè)受傷動(dòng)作,。我們說(shuō)“動(dòng)作游戲世界每一幀都是在變化的”,,因此“每一個(gè)動(dòng)作都是等價(jià)的,,不存在這是什么動(dòng)作的人為概念”——也就是說(shuō),,我們理解的受傷動(dòng)作和攻擊動(dòng)作,在動(dòng)作游戲里都是一個(gè)動(dòng)作,,由此,,動(dòng)作游戲中一個(gè)角色受到攻擊,未必是我們理解的“受傷動(dòng)作”,,比如在《街霸6》中,,也有氣勢(shì)架招等動(dòng)作,受擊之后會(huì)做個(gè)架招成功的動(dòng)作——注意這個(gè)細(xì)節(jié),,是氣勢(shì)架招動(dòng)作,,受到攻擊變成了氣勢(shì)架招成功動(dòng)作,,氣勢(shì)架招成功動(dòng)作自然的下一個(gè)動(dòng)作又是氣勢(shì)架招動(dòng)作,,這是兩個(gè)動(dòng)作,,不是一個(gè)動(dòng)作(狀態(tài)機(jī)思維下,,這會(huì)被理解為一個(gè)狀態(tài),比如防御狀態(tài)),,而在《街霸6》中,氣勢(shì)架招存在Just Block的情況,,Just block跳轉(zhuǎn)的會(huì)是另外一個(gè)動(dòng)作,,所以一共是3個(gè)氣勢(shì)架招相關(guān)的動(dòng)作,,盡管他們可能用的只是2個(gè)動(dòng)作,但是背后的邏輯數(shù)據(jù)的值完全不同,。

圖片

(氣勢(shì)架招動(dòng)作至少有3種:架招,、架招被打中,、just block)


我們對(duì)此做出抽象,,就可以得出一個(gè)說(shuō)法——在動(dòng)作游戲中,,受到攻擊,確切地說(shuō)是受擊框被攻擊框碰到了之后,,雙方都可能發(fā)生動(dòng)作的變化(不變也是一種變化),。那么進(jìn)一步來(lái)看在,這個(gè)問(wèn)題就是這樣的:
●什么攻擊框碰到了哪個(gè)受擊框:這在上文已經(jīng)有提過(guò),我們將一個(gè)角色這一幀所有的攻擊框先按照優(yōu)先級(jí)冒泡,第一個(gè)有碰到另一個(gè)角色受擊框的攻擊框拿出來(lái),,將里面碰到的受擊框按照優(yōu)先級(jí)冒泡,,由此得出“最高優(yōu)先級(jí)的攻擊框,,碰到的最高優(yōu)先級(jí)的受擊框”就是這次“攻擊”的攻擊框和受擊框,。
●下一個(gè)動(dòng)作怎么變:根據(jù)攻擊框的優(yōu)先級(jí)對(duì)抗受擊框的優(yōu)先級(jí),得出誰(shuí)的動(dòng)作“占上風(fēng)”,,我們認(rèn)為優(yōu)先級(jí)高的那個(gè)框(所代表的動(dòng)作)是“占上風(fēng)”的,。“占上風(fēng)”的框中的自身,、對(duì)手兩個(gè)動(dòng)作變化(ActionChangeInfo)就會(huì)告訴我們雙方應(yīng)該怎么變化動(dòng)作,。
●但是ActionChangeInfo中只有一個(gè)目標(biāo)Action.Name:沒(méi)錯(cuò),正是如此,,比如只有"hurt",,但如我們所說(shuō),一個(gè)動(dòng)作(Action)的Name并非Id,,也就是一個(gè)角色身上可以有幾個(gè)甚至幾十個(gè)名字為“hurt”的動(dòng)作對(duì)吧,。那如果我被ActionChangeInfo要求做“hurt”動(dòng)作的時(shí)候,我就會(huì)去看當(dāng)前幀(Character.Frame)中的CancelTag,,然后遍歷我所有名字為“hurt”的動(dòng)作,,一旦這個(gè)動(dòng)作可以用來(lái)Cancel當(dāng)前幀,就會(huì)加入候選列表,。最后這幀邏輯末尾的時(shí)候,,會(huì)根據(jù)候選列表冒泡優(yōu)先級(jí)最高的那個(gè)作為要做的動(dòng)作,所以“下一個(gè)動(dòng)作”是自然地,,誰(shuí)都不知道他具體會(huì)是哪個(gè),,一切都是運(yùn)行時(shí)根據(jù)算法得來(lái)的。
這樣一來(lái),,是不是我當(dāng)前所處的幀,,也會(huì)決定我到底做什么樣的受擊動(dòng)作了?沒(méi)錯(cuò),,正是如此,。

問(wèn)題二:動(dòng)作決定了時(shí)長(zhǎng)了嗎?

當(dāng)“下一個(gè)動(dòng)作”選出來(lái)了以后,,我們是不是就只管做下一個(gè)動(dòng)作就完事兒了,?這是一個(gè)做非動(dòng)作游戲的概念,在動(dòng)作游戲中,碰撞了還有一個(gè)細(xì)節(jié),,分別是卡幀(HitLag)和硬直(HitStun)。
●卡幀的意思是:當(dāng)雙方發(fā)生碰撞(攻擊生效)的時(shí)候,,雙方都會(huì)進(jìn)入卡幀階段,,保持當(dāng)前幀(切換到下一幀之后的當(dāng)前幀)一定幀數(shù),通常攻擊方和挨揍方的卡幀時(shí)長(zhǎng)不同,,攻擊方卡幀會(huì)久一點(diǎn),,這不僅是為了打擊感,也是為了一種平衡性,。
●硬直的意思是:受擊方要做的下一個(gè)動(dòng)作,,并不是下一個(gè)動(dòng)作本身約定的時(shí)長(zhǎng),而是會(huì)通過(guò)下一個(gè)動(dòng)作中的可循環(huán)的幀延長(zhǎng)幀數(shù)來(lái)做到,,因此一個(gè)動(dòng)作游戲中,。
由此可見(jiàn),動(dòng)作游戲中發(fā)生命中的時(shí)候,,每個(gè)角色下一個(gè)動(dòng)作的時(shí)長(zhǎng)是會(huì)變化的,,是動(dòng)態(tài)算出來(lái)的,而根據(jù)算法的不同,,效果也會(huì)有所不同,,在一些做的不太好的動(dòng)作游戲中,遇到大量敵人在同一幀被我同一個(gè)動(dòng)作打中的時(shí)候,,我反而會(huì)硬直很久(源于卡幀)以至于漏出破綻挨打,,當(dāng)然你也可以說(shuō)“就是這么設(shè)定的,習(xí)慣了就好”,。
當(dāng)然具體的卡幀和硬直,,還是根據(jù)攻擊框和受擊框提供數(shù)據(jù)、策劃設(shè)定的算法得出來(lái)的,,因此這也是一個(gè)調(diào)整游戲手感的重要環(huán)境,,同時(shí)一些動(dòng)作也會(huì)因?yàn)樗惴ㄔ诎ご虻臅r(shí)候完全沒(méi)有卡幀,這是允許的,,比如just block動(dòng)作,。

問(wèn)題三:反擊和追擊怎么弄?

看到這里,,相信大家已經(jīng)理解了——“動(dòng)作游戲中,,每個(gè)動(dòng)作都是等價(jià)的,所以沒(méi)有受傷,、格擋一說(shuō)”,,是這樣的,因?yàn)橄乱粋€(gè)動(dòng)作是什么就是什么,花頭全在ActionChangeInfo的配置,,包括當(dāng)身也是——當(dāng)身指的是受到攻擊的時(shí)候立即做出一個(gè)反擊動(dòng)作,,那么就是受擊框的優(yōu)先級(jí)很高,然后“自身動(dòng)作變化”變成一個(gè)攻擊動(dòng)作,。不難理解,,畢竟ActionChangeInfo,是“另一個(gè)渠道的Cancel”,。

圖片


當(dāng)身可以用ActionChangeInfo,,但是追擊(Combo)和反擊要怎么做?他們并不是“全自動(dòng)”跳轉(zhuǎn)的對(duì)吧,,這里就要用到臨時(shí)開(kāi)啟Cancel點(diǎn)的概念了,,還記得我們說(shuō)過(guò)“Cancel點(diǎn)有個(gè)激活狀態(tài)”嗎?就是通過(guò)命中的時(shí)候,,臨時(shí)開(kāi)啟一些CancelTag來(lái)做到這個(gè)效果,,至于開(kāi)啟CancelTag的信息放在哪兒,可以是攻擊框決定雙方,、也可以是受擊框決定雙方,、可以是優(yōu)先級(jí)高的那個(gè)框決定雙方、也可以是各自決定各自的,,每個(gè)游戲做法都不一樣,,這具體還是看策劃游戲的時(shí)候,我們想要咋樣做,,然后進(jìn)一步具體分析,。上文我們提過(guò)的經(jīng)典動(dòng)作游戲中那些第一段打空只會(huì)反復(fù)第一段,打中了才會(huì)進(jìn)行第二段的做法,,也是這樣來(lái)實(shí)現(xiàn)的,。利用好這個(gè)性質(zhì),可以把動(dòng)作游戲的手感和連擊爽快感做到極致,。
03 基于動(dòng)作系統(tǒng)可能產(chǎn)生的玩法創(chuàng)新
在了解了動(dòng)作游戲的動(dòng)作切換系統(tǒng)的做法之后,,我們基于這個(gè)做法可以創(chuàng)作出一些什么玩法呢?畢竟在這個(gè)時(shí)代,,做游戲并不是一件很稀罕的事情,,大家都在做游戲,那我的游戲要能被人看到,,至少得有點(diǎn)特色也就是創(chuàng)新對(duì)吧,。那我們就來(lái)看看一些基于動(dòng)作游戲的動(dòng)作系統(tǒng)可以做的簡(jiǎn)單創(chuàng)新案例。

NO.1

怪物獵人的替換技玩法

這是在《怪物獵人崛起》中開(kāi)始被大家了解到的一個(gè)新系統(tǒng),,事實(shí)上之前《怪物獵人XX》中的狩技也已經(jīng)是這樣了,。這個(gè)玩法就是讓玩家可以在策劃設(shè)計(jì)好的2個(gè)動(dòng)作之間做一個(gè)選擇,,比如玩家可以選擇長(zhǎng)槍沖刺或者架盾沖刺,但是2個(gè)動(dòng)作只能選擇一個(gè),。

圖片


我們拋開(kāi)美術(shù)和策劃設(shè)計(jì)不說(shuō),,即有哪些動(dòng)作可以替換哪些動(dòng)作我們這里不深究,只是探討一下,,從程序開(kāi)發(fā)角度,,這個(gè)替換技玩法怎么做到?實(shí)際上非常非常的簡(jiǎn)單,,就是接著剛才的例子說(shuō),因?yàn)槭翘鎿Q技,,所以Command都是一樣的對(duì)吧,,比如我默認(rèn)給玩家的是長(zhǎng)槍沖刺,他的Command是“強(qiáng)攻擊+弱攻擊”(它能夠Cancel的是架盾動(dòng)作,,但是架盾動(dòng)作本身要按住RT,,所以RT并不在他的Command中,這是一個(gè)錯(cuò)覺(jué)),,那我們配置的時(shí)候,,長(zhǎng)槍沖鋒的Command里面是Command:[[強(qiáng)攻擊,弱攻擊]],而架盾沖鋒因?yàn)槭翘鎿Q技,,所以默認(rèn)配置的Command是Command:[],,也就是沒(méi)有任何操作可以放出架盾沖鋒,但是當(dāng)玩家選擇用架盾沖鋒替換長(zhǎng)槍沖鋒的時(shí)候我們要做的僅僅是 (長(zhǎng)槍沖刺Command, 架盾沖鋒Command)=(架盾沖鋒Command,長(zhǎng)槍沖刺Command)這一句C#代碼就行了——交換了他們的指令之后,,長(zhǎng)槍沖刺的Command就變成了空數(shù)組,,就放不出來(lái)了,而架盾沖鋒的Command里面有了一條就是強(qiáng)攻擊+弱攻擊的,,由于他們的CancelData等都一樣,,就產(chǎn)生了“替換”的效果了。

NO.2

連招自定義build玩法

自定義連招的意思是指把策劃預(yù)設(shè)的一些CancelTag和CancelData交給玩家去在游戲(玩法系統(tǒng))中進(jìn)行設(shè)置,,比如花費(fèi)訓(xùn)練點(diǎn)數(shù)可以開(kāi)啟“力劈華山Cancel白虹貫日”的功能,,即我們把這些Cancel關(guān)系做個(gè)文章,讓玩家通過(guò)調(diào)整Cancel關(guān)系,,來(lái)進(jìn)一步打出自己喜歡的連招來(lái),,組合出自己的流派是一件非常好玩的事情。

NO.3

基于性質(zhì)盡情地去設(shè)計(jì)吧

看,,基于動(dòng)作游戲的動(dòng)作系統(tǒng)的基本性質(zhì),,我們隨手就能很輕易的實(shí)現(xiàn)出兩個(gè)非常好玩、非常有擴(kuò)展性的玩法,。當(dāng)然時(shí)間和篇幅有限,,這里就不提更多的“創(chuàng)意”了,,還是由各位自己在自己的項(xiàng)目中發(fā)揮吧。
但是核心是——?jiǎng)幼饔螒蚝图磿r(shí)回合制游戲,,根本的不同在于他們的實(shí)現(xiàn)方式不同,,實(shí)現(xiàn)方式的不同必然會(huì)帶來(lái)細(xì)節(jié)上的不同,細(xì)節(jié)上的不同就會(huì)帶來(lái)完全不一樣的玩法和體驗(yàn),。
圖片

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多