Unity實現(xiàn)時緩機制的一些注意點
主要和物理模擬相關(guān)。
眾所周知,unity中物理模擬在FixedUpdate前以Time.fixedUpdate(可在Project Setting中調(diào)整)速率進行物理模擬。
PS:Unity的物理引擎,根據(jù)官方文檔顯示
Built-in 3D physics (Nvidia PhysX engine integration)
Built-in 2D physics (Box2D engine integration)
當我們使用Time.scale改變時間速率時,也就是
之后,需要額外處理,來解決一些表現(xiàn)問題。因為由于時間變慢,但物理更新速率沒變,會出現(xiàn)物理幀數(shù)表現(xiàn)不夠,一卡一卡。(也就是說數(shù)值正常,但是表現(xiàn)卡頓)
錯誤做法:假設(shè)我們的時間scale為timescale,那么一個典型的“錯誤”做法是,令代碼調(diào)用:
從表現(xiàn)上來說,這么做能夠使得物理表現(xiàn)恢復(fù)“絲滑”,因為此時提高了物理更新速率。但是如果在一段物理模擬過程中,突然改變Time.fixedUpdateTime,也就是dt,那么物理模擬會出現(xiàn)錯誤。因為Unity物理模擬是實時解算,有賴于上一幀的結(jié)果和dt的穩(wěn)定,此時改變dt一定會導(dǎo)致接下來的物理解算出錯。所以這個“錯誤”做法不能用于物理過程中改變Time.scale。
正確做法:
第一,我們可以去Project Setting里適當降低fixedUpdateTime,以提高基礎(chǔ)的物理模擬速率。
第二,對于RigidBody,在時緩時使用
來開啟自帶的插值功能,使得表現(xiàn)變順滑。
第三,對于我們自己實現(xiàn)的(在FixedUpdate中更新的)一些位移或者旋轉(zhuǎn)邏輯,我們自己去Update里實現(xiàn)我們自己的順滑插值。至于怎么實現(xiàn),需要我們有最基本的物理模擬插值認知。
我們自己位移邏輯的物理插值實現(xiàn)例子:
假設(shè)我們之前在FixedUpdate中維護了一個功能dash,用于每物理幀往一個方向沖刺:
那現(xiàn)在要改寫。一個最簡單常見的插值思路是,假定每一物理幀瞬間都是勻速直線運動,那么就可以根據(jù)上一個物理幀的位置,預(yù)測當前位置,直到下一個物理幀再硬set回正確位置。(看似暴力,但實際上可以應(yīng)付99%的情況,并且在極端情況下,即使多考慮一些幀數(shù)信息也不一定能更好預(yù)測,除非上卡爾曼濾波,那就太復(fù)雜了。其實SLAM領(lǐng)域里也是這么做的)
改寫物理幀如下:
然后在Update函數(shù)里,進行插值:
至此,Unity中實現(xiàn)時緩機制的一些問題就解決了。