遊戲性能優化雜談(六) - 知乎

遊戲邏輯的執行,也是CPU端性能瓶頸的常見緣由之一。程序員

當代遊戲引擎的一大進步,是將遊戲邏輯的製做從程序員手中解放出來。WYSIWYG的可視化編輯,基於腳本語言甚至是節點連線的二次開發,都大大下降了編寫遊戲邏輯的技術門檻。可是正如老話所說,「甘蔗不能兩頭甜」,這一切是以CPU端的執行性能犧牲做爲代價的。性能

在我經歷過的各類軟件行業和軟件項目當中,遊戲能夠說是最爲在面向對象這個問題上糾結的一個了。一方面,遊戲自己內容的組織上具備很是強的對象特性:無非是一羣actor在一個舞臺上按照劇本表演,而且根據一些預設邏輯與玩家(的代理)互動。因此從這個角度來講,以面向對象的手法去開發遊戲看起來是最爲符合人的直覺的。測試

可是另一方面,面向對象在理論上假設各個對象是自治的,並行的。可是實際的執行平臺的資源倒是高度受限的。這就致使CPU必須採用一種相似時分複用的方式,將執行時間分配給遊戲當中的衆多對象來推演其狀態變化。並且,這種推演必須被送給全部處於活動狀態當中的對象:由於在面向對象的思路當中,對象的狀態是由其自身管理的,外部只能經過交互去影響,但不能去直接決定。動畫

這就是說,引擎在每一個CPU週期當中,必須去遍歷全部處於活動狀態的對象,而且調用其一系列方法,去驅動其狀態的改變,哪怕該對象其實與玩家並不會有任何交互。設計

幾年前有幾款上PS平臺的獨立遊戲,問題就發生在這裏。當畫面當中的敵人一多,畫面就開始瘋狂掉幀。後來分析發現,由於敵人其實就是那麼幾種類型,根據面向對象的概念,遊戲開發者製做了這幾種類型敵人的stereotype(原型),而後不斷的instance(實例化)來生成敵人。由於這些敵人都是對應的同一個原型,它們各自都會在每一幀完整執行全部的遊戲邏輯腳本,包括攻擊斷定等。可是,實際上真正可以摸着玩家的就那麼幾個,其它大部分由於攻擊距離等問題是沒有可能摸到玩家的可是它們的相關腳本依然是在不斷被執行,白白浪費CPU資源。代理

對於這種狀況,其實之前的面向過程的設計方式,每每可以得到更加優秀的性能。與其盲目推演各個對象的狀態機來斷定攻擊行爲,不如根據攻擊時間和範圍來直接更新各個actor的狀態。對象

再舉一個例子。數年前有一款射擊遊戲,製做者也是將子彈stereotype化,給它掛了一個腳本,負責其移動和命中斷定。可是後來發現子彈一多就開始瘋狂掉幀。其實,只要不是導彈或者制導炸彈,子彈一經射出軌跡就是固定的。那麼,子彈可否命中其實就是一個簡單的求交問題,大部分狀況並不須要每幀都去測試一下。至於子彈的飛行,其實只要軌跡肯定,剩下的基本就是沿着軌跡的動畫播放,根本不須要狀態的推演。遊戲

遊戲在不少時候都是障眼法,用1幀計算結果,用好幾幀進行表演。若是無論三七二十一什麼都用OO那套一幀一幀的去推演狀態機,那性能天然是不會太好的。資源

相關文章
相關標籤/搜索