最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

對(duì)方舟幀數(shù)問題的最終解答

2020-10-09 08:52 作者:等--等燈等燈  | 我要投稿

前言

本文內(nèi)容為合作完成,在此特別感謝?@fux2?和?@沒有-MeiYou?兩位大佬的幫助
本文將會(huì)以近期盛傳的史爾特爾/燧石/棘刺攻速bug為線索,從程序?qū)用嬷v解攻速與幀數(shù)相關(guān)的機(jī)制問題
并對(duì)困擾玩家一年多的幀數(shù)問題進(jìn)行解答


所謂“幀數(shù)”

眾所周知,方舟是一個(gè)“30幀”的游戲
但這個(gè)“30幀”并非常規(guī)意義上的每秒30張畫面,而是指程序的最大自動(dòng)更新頻率
這個(gè)更新通過unity引擎自帶的FixedUpdate函數(shù)實(shí)現(xiàn),其中更新間隔為變量fixedDeltaTime,這個(gè)變量在方舟中為1/30
FixedUpdate函數(shù)會(huì)在每次被執(zhí)行時(shí)執(zhí)行battleController以及其包含所有BObject(包含實(shí)體,地磚等)的OnTick函數(shù)
然后實(shí)體的OnTick函數(shù)又會(huì)執(zhí)行其包含的技能,能力,狀態(tài)等等的OnTick函數(shù)
這些能力又會(huì)執(zhí)行其包含的計(jì)時(shí)器的OnTick()函數(shù)...
以此類推,最后達(dá)到讓所有需要更新的類都以固定的頻率進(jìn)行自動(dòng)更新的目的
畫面(包括spine動(dòng)畫,場(chǎng)景,特效等等)不包含在此類中


浮點(diǎn)精度

BV1qD4y1R7tN中,UP主提到了一個(gè)測(cè)試結(jié)果,即嘗試使用OnTick函數(shù)輸出幀與幀之間的間隔時(shí),發(fā)現(xiàn)幀的間隔在128s-256s之間發(fā)生了變化(幀的間隔變的更長(zhǎng)了)

視頻中給出的128s附近的測(cè)試結(jié)果

然而,事實(shí)真的如此嗎?

首先我們需要了解一下測(cè)試中輸出幀間隔的方法
游戲中有一個(gè)名為get_fixedPlayTime的函數(shù),可用來獲取游戲從開局到現(xiàn)在所經(jīng)歷的游戲時(shí)間
這個(gè)游戲時(shí)間為一個(gè)float變量,會(huì)被FixedUpdate函數(shù)所更新,每次更新會(huì)使其增加fixedDeltaTime(即1/30)
而輸出幀間隔,是在FixedUpdate函數(shù)上調(diào)用get_fixedPlayTime來輸出當(dāng)前游戲時(shí)間
之后通過兩次游戲時(shí)間相減來獲取“幀間隔”(即FixedUpdate函數(shù)被調(diào)用的間隔)

從數(shù)學(xué)的角度上來說,這么做沒有任何問題
但是從計(jì)算機(jī)的角度出發(fā),這樣做可能會(huì)帶來嚴(yán)重的誤差
其原因在于,float變量所能表示的有效數(shù)字(即sig fig)位數(shù)有限
在游戲時(shí)間為128.03333333s時(shí),小數(shù)點(diǎn)后的第5位已經(jīng)變成了第八位有效數(shù)字,這很可能會(huì)在減法時(shí)造成誤差
讓我們實(shí)際測(cè)試一下

可以看到,雖然以上兩個(gè)運(yùn)算在數(shù)學(xué)上不會(huì)存在任何結(jié)果的差異
但在計(jì)算機(jī)上,由于浮點(diǎn)數(shù)的精度問題,結(jié)果被改變了
那么這里可以得出結(jié)論,所謂“幀的間隔”的改變,實(shí)際上并不存在,這僅僅是測(cè)試輸出結(jié)果時(shí)由于浮點(diǎn)精度問題造成的誤差

但是,128s-256s時(shí),史爾特爾在游戲中攻擊間隔的改變是切實(shí)存在的
因此可以推測(cè),鷹角應(yīng)該在哪里犯了和之前測(cè)試類似的錯(cuò)誤


攻擊后搖

最終我們?cè)诠艉髶u的時(shí)長(zhǎng)計(jì)算里找到了可能存在的浮點(diǎn)精度問題

首先需要對(duì)攻擊的邏輯進(jìn)行一定的解釋
攻擊屬于一種特殊的能力(ability)
大部分情況下,每播放一次完整的攻擊動(dòng)畫(這里不考慮什么首次接敵的抬手動(dòng)作之類的)視作一次完整的攻擊
一次完整的攻擊的流程為:攻擊開始(CastStart)——前搖(PreDelay)——造成效果(event/SpellOn)——后搖(PostDelay)——攻擊結(jié)束(CastEnd)
攻擊開始時(shí)會(huì)根據(jù)當(dāng)前攻速,攻擊動(dòng)畫長(zhǎng)度,攻擊動(dòng)畫最大拉伸比例,計(jì)算出本次攻擊持續(xù)時(shí)間,然后以此時(shí)間計(jì)算速度播放攻擊動(dòng)畫
前搖開始時(shí)會(huì)記錄下當(dāng)前的游戲時(shí)間(fixedPlayTime),作為開始時(shí)間。前搖持續(xù)會(huì)被化為整幀
攻擊依賴于動(dòng)畫時(shí),接收到來源于spine動(dòng)畫的攻擊事件時(shí)結(jié)束前搖,造成效果,隨后進(jìn)入后搖
后搖開始時(shí)會(huì)獲取當(dāng)前游戲時(shí)間,并以?后搖持續(xù)時(shí)間=攻擊持續(xù)時(shí)間-(當(dāng)前游戲時(shí)間-開始時(shí)間),計(jì)算出后搖時(shí)間。隨后后搖時(shí)間會(huì)被四舍五入至整幀
后搖結(jié)束時(shí),本次攻擊結(jié)束,播放攻擊結(jié)束動(dòng)畫

計(jì)算后搖持續(xù)時(shí)間時(shí),由于獲取了兩次游戲時(shí)間,因此計(jì)算出的后搖持續(xù)時(shí)間很可能存在浮點(diǎn)精度問題
我們獲取了史爾特爾在128s附近計(jì)算出的后搖時(shí)間(未經(jīng)過四舍五入)

史爾特爾在128s附近計(jì)算出的后搖時(shí)間

從圖片中可看出,在0-128s時(shí),計(jì)算出后搖持續(xù)為0.850006s,略大于25.5幀。經(jīng)過四舍五入后變?yōu)?6幀
而在128s后,計(jì)算出后搖持續(xù)為0.849915s,略小于25.5幀。經(jīng)過四舍五入后變?yōu)?5幀
這樣一來,由于前搖時(shí)間不變,后搖時(shí)間短了一幀,因此在128s后,史爾特爾的攻擊較正常情況會(huì)提早一幀結(jié)束
即,普通狀態(tài)下,攻擊持續(xù)1.26667s(38幀)。128s后,攻擊持續(xù)1.23333s(37幀)。


等等...明明128s后攻擊持續(xù)減短了,為什么攻擊間隔反而多了一幀???


觸發(fā)順序

攻擊持續(xù)比攻擊間隔短的干員,攻擊間隔往往莫名其妙多出一幀
這和攻擊的觸發(fā)與冷卻機(jī)制有關(guān)

首先是攻擊/主動(dòng)能力的冷卻機(jī)制
攻擊擁有獨(dú)立的冷卻計(jì)時(shí)器(使用倒計(jì)時(shí)),不跟關(guān)卡時(shí)間掛鉤,但是依然是以幀為間隔進(jìn)行更新
攻擊會(huì)在開始的瞬間進(jìn)入冷卻。依賴攻速時(shí),冷卻會(huì)被設(shè)置為理論攻擊間隔
冷卻為0,且攻擊未處于發(fā)動(dòng)狀態(tài)的情況下,才可觸發(fā)下一次攻擊

對(duì)于史爾特爾128s后的情況,在1.23333s時(shí),冷卻計(jì)時(shí)器尚未歸0,因此無法進(jìn)行下一次攻擊
那么為什么1.266667s時(shí),理論上冷卻已經(jīng)歸0,卻依然無法觸發(fā)呢?
因?yàn)閮蓚€(gè)邏輯的共同作用:
第一:在執(zhí)行FixedUpdate時(shí),攻擊的觸發(fā)判定(即狀態(tài)機(jī)tick),始終位于能力的冷卻更新之前
第二:在能力執(zhí)行的第1幀里,不會(huì)進(jìn)行冷卻更新


這么說可能有點(diǎn)迷,所以這里做了張圖

鷹角的神奇邏輯

由圖中可以看出,在鷹角的邏輯下,所有攻擊冷卻周期在實(shí)際應(yīng)用中會(huì)比理論情況多一幀
4幀的冷卻周期在鷹角的邏輯下變?yōu)榱?幀

部分干員(如克洛斯)并沒有出現(xiàn)這樣的問題
其原因是,方舟有一個(gè)特殊機(jī)制(Ability.FinishCallbackDelegate):攻擊結(jié)束后,會(huì)立刻嘗試觸發(fā)下一次攻擊
因此,攻擊持續(xù)時(shí)間等于攻擊間隔的干員并不會(huì)出現(xiàn)多一幀的現(xiàn)象

而史爾特爾,本應(yīng)攻擊持續(xù)等于攻擊間隔。但由于之前所描述的浮點(diǎn)精度問題,導(dǎo)致攻擊實(shí)際持續(xù)較攻擊間隔短了0.5幀
從而引起了“多一幀”的問題
類似的還有源石地板上的專三至高之術(shù)棘刺


冷卻重置

除去以上這些機(jī)制外,還有一個(gè)被稱作冷卻重置(resetCDStrategy)的機(jī)制
這個(gè)機(jī)制的大概效果為,在攻擊結(jié)束時(shí)(CastEnd,位于立刻嘗試觸發(fā)下一次攻擊之前),會(huì)檢查剩余的冷卻
如果這個(gè)冷卻小于一個(gè)固定值(目前除白金為0外其它干員均為半幀),則立刻重置攻擊的冷卻

這個(gè)機(jī)制反應(yīng)到表層就是所謂的幀對(duì)齊,或者是攻速化成幀的四舍五入
但是,由于這個(gè)機(jī)制只在攻擊結(jié)束時(shí)生效,因此如果攻擊持續(xù)小于攻擊間隔0.5幀或以上,不要考慮四舍五入的事情

最典型的例子是這次的燧石攻速問題
燧石理論攻擊間隔0.78s,為23.4幀
由于實(shí)際攻擊動(dòng)畫持續(xù)只有21幀,因此無法觸發(fā)冷卻重置,實(shí)際冷卻應(yīng)向上取整,為24幀
又因?yàn)閯?dòng)畫短于攻擊間隔0.5幀以上,受到“多一幀”問題的影響,實(shí)際冷卻周期為25幀,即0.833s,和實(shí)際攻速一致


其它問題

主要有小羊火山的攻擊間隔多一幀問題
實(shí)際原因?yàn)楹髶u擁有1幀保底。進(jìn)行15幀前搖,未等待到攻擊事件后強(qiáng)制進(jìn)入1幀后搖,導(dǎo)致實(shí)際攻擊間隔為16幀。

安潔莉娜2技能的攻擊次數(shù)損失原理同火山,攻速不穩(wěn)問題可參考cv6376654


本文原載于NGA:https://ngabbs.com/read.php?tid=23640215

作者為本人

此專欄以CC BY-NC-SA 4.0協(xié)議發(fā)布

對(duì)方舟幀數(shù)問題的最終解答的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
桦南县| 安泽县| 门头沟区| 沂水县| 郸城县| 江津市| 化州市| 承德市| 富宁县| 乡城县| 农安县| 龙江县| 台湾省| 镇雄县| 义马市| 沁源县| 鲁甸县| 望江县| 博客| 阳朔县| 雅江县| 青川县| 龙海市| 综艺| 孝昌县| 太保市| 黄梅县| 广水市| 陆丰市| 定襄县| 泌阳县| 湖北省| 平乡县| 厦门市| 思南县| 曲阳县| 锦屏县| 石河子市| 砀山县| 客服| 鹤峰县|