用 Unity 探究 2D 游戏的打击感
引言
這是我畢業(yè)設(shè)計(jì)的一部分emmm……我的畢設(shè)和格斗游戲相關(guān),而對(duì)于打擊感的研究算是其中我比較在意的一環(huán)?,F(xiàn)在臨近畢業(yè),我將畢設(shè)中開(kāi)發(fā)部分的一些內(nèi)容整理出來(lái)分享,希望能通過(guò)這樣學(xué)習(xí)到更多的東西。
打擊感為何物?
字面意思,“打到了的感覺(jué)”;好的打擊感是易讀的,包含信息充足的;它可以讓玩家感受到這次的攻擊奏效了、這次攻擊的輕重程度、感受到這是怎樣的攻擊。在電子游戲中,則通過(guò)視覺(jué)和聽(tīng)覺(jué)呈現(xiàn)這些。
實(shí)現(xiàn)方式
市面上已經(jīng)有很多作品供我們參考,讓我自己想出一個(gè)獨(dú)特的實(shí)現(xiàn)方式如同天方夜譚,不過(guò)我喜歡參照已有作品,去探究他們?nèi)绾螌?shí)現(xiàn)。
1)幀凍結(jié)(頓幀)
頓幀已經(jīng)是司空見(jiàn)慣的手段,也是目前最常見(jiàn)的表現(xiàn)打擊感的方式。它會(huì)讓角色動(dòng)畫(huà)停止在那里,讓玩家意識(shí)到發(fā)生了什么,接著再繼續(xù)播放動(dòng)畫(huà)。我認(rèn)為所有的打擊感幾乎都有這個(gè)東西,只不過(guò)可能有些幀凍結(jié)的時(shí)間設(shè)置,讓人很難用肉眼察覺(jué)到。在《街霸4》中,擊中時(shí)普遍的頓幀時(shí)間為:攻擊角色頓14/60幀≈0.23秒,受擊角色頓16/60幀≈0.26秒,是我見(jiàn)過(guò)最長(zhǎng)的。
一般情況下,頓幀的時(shí)間不會(huì)超過(guò)0.3秒,除非是做特殊的效果處理,因?yàn)槌^(guò)0.3秒這個(gè)圖像在玩家眼里會(huì)變得非常突出,顯得較為奇怪。通常程度越重的攻擊頓幀的時(shí)間也越長(zhǎng),而這也需要適當(dāng)?shù)膭?dòng)作設(shè)計(jì),比如較長(zhǎng)時(shí)間的出手準(zhǔn)備動(dòng)作能讓玩家對(duì)這次攻擊有一個(gè)“很重”的預(yù)期。
2)擊退距離
除非有特殊需求,不然大多數(shù)游戲在攻擊后,雙方角色之間的距離一定會(huì)產(chǎn)生變化。這是非常容易表現(xiàn)一個(gè)攻擊輕重程度的方式。
頓幀+擊退是我認(rèn)為最主要的兩個(gè)方式,運(yùn)用這兩者,即可實(shí)現(xiàn)最基本的打擊感。那么在這基礎(chǔ)上,可以添加一些“特效”來(lái)使它更加充實(shí)。
3)特效
可以有很多種,我認(rèn)為這些就像是在打擊感上加花,使它更加豐滿。我通過(guò)總結(jié),列舉了一些常見(jiàn)手段:
1.打擊火花(HitFire):攻擊奏效時(shí)在特定位置創(chuàng)建。需要注意畫(huà)風(fēng)適當(dāng),風(fēng)格對(duì)應(yīng);斬?fù)粲袛負(fù)舻臉邮?#xff0c;拳擊有拳擊的樣式,重攻擊應(yīng)該比輕攻擊的火花更大更飽和等等。
2.精靈(Sprite)抖動(dòng):我們?cè)诤芏嘤螒蚶锟赡芏紩?huì)看到,當(dāng)角色受到攻擊時(shí),幀凍結(jié)期間角色的圖片(Sprite)也在顫動(dòng),顫動(dòng)的方式有多種,水平及垂直方向的,或是虛影向外擴(kuò)張的(我不知道那種形式該怎么表述)。但這僅限于視覺(jué)上的抖動(dòng),該抖動(dòng)不會(huì)有任何邏輯上的影響,比如角色的物理坐標(biāo),判定框這些均不會(huì)隨著精靈的抖動(dòng)而改變。
3.屏幕震動(dòng):很多游戲都會(huì)通過(guò)震屏來(lái)彰顯一次攻擊的沖擊力,震屏的方式以及怎樣去表現(xiàn)不同的攻擊,這值得研究。
4.顏色變化:有些動(dòng)作游戲會(huì)讓角色在受擊的時(shí)候,身體顏色產(chǎn)生變化,大多是在那一瞬間,身體閃一下相應(yīng)顏色,紅色和白色較為常見(jiàn)。這會(huì)讓玩家更容易讀出角色正在挨打這件事。
本次畢設(shè)我主要采取了幀凍結(jié)+擊退+精靈抖動(dòng)+打擊火花的組合進(jìn)行實(shí)現(xiàn)。
下面是在Unity中的應(yīng)用:
1.HitBox與HurtBox的搭建
先簡(jiǎn)單說(shuō)下我對(duì)游戲中攻擊和受擊的實(shí)現(xiàn)吧。
?
我的角色總共有3種攻擊方式,而我為每一種攻擊方式在角色下面都創(chuàng)建了一個(gè)子物體;
?
每一個(gè)攻擊子物體,都有他們對(duì)應(yīng)的BoxCollider2D(IsTriiger)來(lái)代表他們的攻擊判定,同理,HurtBox也一樣。
我用Animator的幀事件控制每個(gè)攻擊動(dòng)作開(kāi)啟攻擊判定的時(shí)機(jī)和位置。
?
我會(huì)在OnTriggerEnter2D函數(shù)里面實(shí)現(xiàn)攻擊需要發(fā)生的事情,若攻擊物體碰到了標(biāo)簽為“Hurt2”(2P的受擊判定框)的物體時(shí),攻擊便發(fā)生了。
2.邏輯流程
在討論實(shí)現(xiàn)之前,我想先梳理一下邏輯流程,先是攻擊角色的流程:
?
- 首先,在Hitbox與HurtBox重疊時(shí),我們會(huì)判定為攻擊奏效,此時(shí)我會(huì)優(yōu)先處理的是關(guān)閉HitBox,因?yàn)槲也幌M羰录貜?fù)發(fā)生,避免一些麻煩;
- 之后是“頓幀”,我通過(guò)控制動(dòng)畫(huà)播放速度,使速度為0來(lái)實(shí)現(xiàn)這一功能;
- 接著我們需要記錄下角色當(dāng)前的速度(X軸和Y軸),因?yàn)榻酉聛?lái)我們要鎖定角色的位移了,在幀凍結(jié)期間,我們不希望角色的位置仍在變化;
- 創(chuàng)建火花特效,創(chuàng)建的位置我希望是在判定框相交區(qū)間的中心位置;
- 頓幀結(jié)束,恢復(fù)動(dòng)畫(huà)播放;
- 恢復(fù)角色之前被記錄的速度,若本次攻擊是空中攻擊,那么這之后角色會(huì)繼續(xù)下落了;
?對(duì)角色施加對(duì)應(yīng)方向的力,以達(dá)到擊退的效果,手機(jī)靚號(hào)交易平臺(tái)也可以是垂直方向的力,達(dá)到浮空或強(qiáng)DOWN之類(lèi)的效果。
那么總結(jié)下來(lái),流程就是:
關(guān)閉HitBox→停止動(dòng)畫(huà)播放→記錄當(dāng)前速度→鎖定角色的X軸Y軸→創(chuàng)建火花→恢復(fù)動(dòng)畫(huà)播放→恢復(fù)角色速度→施加力(擊退)
對(duì)于受擊角色來(lái)說(shuō)也是類(lèi)似,不過(guò)會(huì)多出一個(gè)抖動(dòng)的效果,并且不用記錄角色速度:
進(jìn)入受擊動(dòng)畫(huà)→停止動(dòng)畫(huà)播放(此時(shí)應(yīng)處于受擊動(dòng)畫(huà)的第一幀)→處理精靈抖動(dòng)(抖動(dòng)時(shí)間應(yīng)小于頓幀時(shí)間)→恢復(fù)動(dòng)畫(huà)播放→施加力
好的,整理完了流程,可能在講實(shí)現(xiàn)方式的時(shí)候思路會(huì)更清晰一些。
3.幀凍結(jié)的實(shí)現(xiàn)
我通過(guò)控制Animator的播放速度和Invoke函數(shù)這兩者結(jié)合來(lái)實(shí)現(xiàn)幀凍結(jié)這一功能。
Invoke可以讓規(guī)定的函數(shù)在規(guī)定時(shí)間后啟動(dòng),而我在Invoke函數(shù)中使用的HitStop_AS參數(shù)就是攻擊擊中后攻擊角色自身的幀凍結(jié)時(shí)間,這里的參數(shù)需要以秒為單位。
在定義變量時(shí),HitStop這一類(lèi)參數(shù)是以幀為單位定義的,在public之后我可以在Unity界面中很方便的以幀的概念進(jìn)行調(diào)節(jié),在游戲開(kāi)始時(shí),便會(huì)通過(guò)Start()里面的指令轉(zhuǎn)化為秒單位。
我創(chuàng)建了名為HitStop的腳本,這些都是寫(xiě)在那個(gè)腳本里的,而我會(huì)給每個(gè)攻擊子物體都套上這個(gè)腳本,這樣每一個(gè)攻擊招式都具備這些模板一樣的變量了。對(duì)此我進(jìn)行了一系列的總結(jié)。
表1攻擊招式應(yīng)具備的模板屬性
屬性備注
動(dòng)畫(huà)總幀/anim完整攻擊動(dòng)畫(huà)的幀數(shù);不可調(diào)整
發(fā)生/A概念變量,攻擊判定產(chǎn)生前的幀數(shù);可調(diào)整
攻擊持續(xù)/KA概念變量,攻擊判定持續(xù)存在的幀數(shù);可調(diào)整
擊中時(shí)的頓幀/HitStop_AS擊中時(shí)自身動(dòng)畫(huà)停止播放的幀數(shù);可調(diào)整
被擊中者的頓幀/HitStop_AO被擊中者動(dòng)畫(huà)停止播放的幀數(shù);可調(diào)整
被防時(shí)的頓幀/HitStop_DS被防御時(shí)自身動(dòng)畫(huà)停止播放的幀數(shù);可調(diào)整
防御者的頓幀/HitStop_DO防御者動(dòng)畫(huà)停止播放的幀數(shù);可調(diào)整
表2受擊方相關(guān)屬性
屬性備注
受擊動(dòng)畫(huà)總幀/anim_o完整受擊動(dòng)畫(huà)的總幀數(shù);不可調(diào)整
防御動(dòng)畫(huà)幀/anim_d完整防御動(dòng)畫(huà)的總幀數(shù);大多情況下防御動(dòng)畫(huà)都是一張同樣的圖持續(xù)多幀;不可調(diào)整
表3其他相關(guān)屬性
屬性備注
黃金受擊幀/zhexue受擊頓幀結(jié)束后,受擊動(dòng)畫(huà)至少要播放的幀數(shù)。即這個(gè)幀數(shù)會(huì)讓玩家明確的感受到第二次攻擊生效了;想達(dá)到這個(gè)效果,夸張的受擊動(dòng)畫(huà)設(shè)計(jì)是必要的,動(dòng)作幅度越大,感受就越直觀;目前還沒(méi)有一個(gè)明確的答案能解釋多少幀合適,但動(dòng)作改變幅度明顯即可。
連招間歇幀/ComboBreak攻擊者的第一招命中后,輸入可以形成連招的第二招之前允許玩家間隔的最大幀
?
這里有很多是我自己總結(jié)的一些概念,像是一些公式也只是出于玩家視角理解的知識(shí)進(jìn)行總結(jié);格斗游戲現(xiàn)在已經(jīng)發(fā)展成了“電子競(jìng)技”,對(duì)于玩家來(lái)說(shuō),“有利幀”“不利幀”這些都已成為了必修功課,所以我認(rèn)為這些也有必要列入到設(shè)計(jì)工作當(dāng)中,而這些公式或許能幫助我在開(kāi)發(fā)中提供更多的便利,僅供參考。
4.打擊火花的創(chuàng)建
先前我使用了從不同游戲中的拿過(guò)來(lái)的美術(shù)素材進(jìn)行實(shí)驗(yàn),畫(huà)風(fēng)的不統(tǒng)一會(huì)讓人覺(jué)得很不舒服,因?yàn)檫@是最直觀的感受,所以我后來(lái)挑了一整套同一個(gè)游戲的素材,效果好多了。
我認(rèn)為,合適的火花特效非常重要。同時(shí),特效創(chuàng)建的位置也應(yīng)合理,我希望火花創(chuàng)建在HitBox與HurtBox相交區(qū)間的中心處。
為此,我自定義了一個(gè)二維向量,用來(lái)計(jì)算相交區(qū)間的中心坐標(biāo):
?
之后通過(guò)Instantiate()函數(shù)在OnTriggerEnter2D()中實(shí)現(xiàn)創(chuàng)建的功能。
5.精靈抖動(dòng)
角色sprite的抖動(dòng)僅限于視覺(jué)上,角色的物理坐標(biāo)不會(huì)隨著抖動(dòng)而變化。為了實(shí)現(xiàn)這一邏輯,我在sprite物體上創(chuàng)建了一個(gè)父物體,而角色的物理BoxCollider以及RigidBody等組件都會(huì)套在這個(gè)父物體上。
?
父物體的運(yùn)動(dòng)會(huì)影響到子物體,但子物體的運(yùn)動(dòng)不會(huì)影響父物體,這樣在Sprite抖動(dòng)的時(shí)候就不會(huì)影響到物理判定框了。
?
我為此定義了3個(gè)變量,A為抖動(dòng)的振幅,speed為抖動(dòng)的速度,即抖動(dòng)頻率的控制,x會(huì)按照speed定義的速度持續(xù)增加。
若判定抖動(dòng)觸發(fā)(bool==true),則讓角色Sprite的X坐標(biāo)等于A*Mathf.Cos(x)的值,借由三角函數(shù)的函數(shù)圖像可知,若x一直遞增,坐標(biāo)便會(huì)呈現(xiàn)波動(dòng)態(tài)。
連擊預(yù)輸入的實(shí)現(xiàn)
?
我將每一個(gè)攻擊動(dòng)畫(huà)都分為了三個(gè)區(qū)間,并且定義了一個(gè)bool值;
當(dāng)進(jìn)入到第二個(gè)(圖中黃色)區(qū)間時(shí),便會(huì)開(kāi)始檢測(cè)玩家是否按下了攻擊鍵,若按下攻擊鍵,則給bool變量賦值true;到第三個(gè)區(qū)間時(shí),便會(huì)開(kāi)始檢測(cè)bool值的真假,若為真,則允許動(dòng)畫(huà)切換到下一個(gè)攻擊動(dòng)作。而在每個(gè)動(dòng)畫(huà)的第一幀,將bool值重新置為false。
一般我會(huì)在允許動(dòng)畫(huà)切換的關(guān)鍵幀前面留2-3幀作為預(yù)輸入的區(qū)間。
總結(jié)
那么,這是最終實(shí)現(xiàn)出來(lái)的效果:錄像軟件和GIF制作出來(lái)的效果不能很好的表達(dá)出來(lái)……
?
本次畢設(shè)研究主要以視覺(jué)表現(xiàn)為主;一個(gè)合適的音效的確能給打擊感帶來(lái)更好的體驗(yàn),但一個(gè)好的打擊感主要還是通過(guò)視覺(jué)反饋造就的。玩家在按下按鍵的一瞬間或是按鍵之前心里就已經(jīng)有了相應(yīng)的預(yù)期,而產(chǎn)生的結(jié)果如果符合或超過(guò)玩家的預(yù)期則證明該反饋是優(yōu)秀的。
不難理解為什么有人只通過(guò)看視頻就想要對(duì)打擊感評(píng)頭論足,因?yàn)槿藗兏谝飧泄俦憩F(xiàn),因?yàn)槟呛苤庇^,盡管操作手感也包括在打擊感的一環(huán)里,但并不是沒(méi)有僅憑視覺(jué)就讓人稱(chēng)贊的作品。
通過(guò)這次畢設(shè)的實(shí)驗(yàn),我發(fā)現(xiàn)也許打擊感更多要靠美術(shù)去表現(xiàn)。程序上的實(shí)現(xiàn)手段總結(jié)了下來(lái)大多都能理解,運(yùn)用得當(dāng)即可。但我在任何參數(shù)都沒(méi)改變的情況下,僅僅換了一整套更高質(zhì)量的美術(shù)資源,呈現(xiàn)出來(lái)的效果卻讓我感覺(jué)好了很多。上面在說(shuō)明“幀凍結(jié)”的時(shí)候提到過(guò),一次好的打擊感也需要有好的動(dòng)作設(shè)計(jì)和上乘的美術(shù)表現(xiàn)。通過(guò)實(shí)驗(yàn),我對(duì)此有了較為深刻的印象。
我希望能通過(guò)分享和交流學(xué)習(xí)到更多的東西。
以上這些主要為我的畢業(yè)設(shè)計(jì)中系統(tǒng)開(kāi)發(fā)的一部分,有很多地方?jīng)]有說(shuō)明為何要這樣做。希望有機(jī)會(huì)能將更多的東西整理出來(lái)吧。
總結(jié)
以上是生活随笔為你收集整理的用 Unity 探究 2D 游戏的打击感的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 腾讯游戏学院专家分析:Unity在移动设
- 下一篇: 用unity制作简单的太空游戏(1):简