開發的一個rts moba遊戲在手機上的性能不大好,如何進行優化?
目前在做一個手機端的moba遊戲。先不管設計者角度,單從技術的演算法角度,遇到了這樣的問題:目前邏輯幀僅能設成4~6幀/秒,才能讓有50個不到的獨立AI單位的戰鬥勉強維持30fps。。
演算法上,使用unity+幀同步(完全不用物理引擎),有xz平面的碰撞檢測+解決(四叉樹),尋路使用基於grid的a*,ai使用行為樹,另外為了熱更和技能buff和ai配置更方便,很大一部分遊戲邏輯採用lua。另外,由於策劃要求,所有的普攻和大部分技能彈道全是指向型(即均為lol里EZ的技能,或war3里的牛頭的t、恐懼的c).. 這樣就造成了如果邏輯幀率設得低,飛行速度快一點的飛彈很可能直接會直接穿過碰撞體積小的單位。。。在演算法和性能上,有人能給點建議不?ps:目前計劃用rvo幹掉ai單位間的碰撞,同時忽視玩家操作產生的單位碰撞、尋路用小區域a*尋路而不是全圖的....另外lua與c#交互的開銷略大,想把核心計算邏輯採用更高效的語言實現,c/c++也許會更好?
說說尋路方面的優化吧。
兩年前做過一個RTS類型的C++尋路移動庫。帶碰撞,帶RVO,還有各種repath檢測,formation之類的。寫的lib最後用在一個手游項目上,100個單位,peak不超過4ms。有時個別情況單個A*時間過長的,可以調整一些參數來優化。
所以理論上來說,移動平台上的性能應該不是問題,更多的是效果和性能的妥協。(不好意思審題不仔細,你要用lua寫,這就沒什麼好說的了)之前找工作,在電腦的編輯器上錄了一段demo的視頻。(因為項目掛了後,IOS更新版本後已經跑不了。。)Unit Flocking Robustness
由於是剛工作時做的東西,現在看來還有不少優化的空間,比如可以加上JPS。JPS+: Over 100x Faster than A*。
總的來說,要做個帶碰撞的,用於RTS的movement,坑挺多,簡單說幾個印象中的性能方面影響比較大的地方。
1、Sliced A*
限制每幀A*計算迭代次數,做幀率和效果的平衡。當然如果用JPS可以是忽略這個問題。2、visibility test和reactive pathfollow
pathfollow其實可以算是movement的核心問題,特別對帶碰撞的情況。Pathfollow是否。Valve的reactive pathfollow效果挺不錯,。演算法方面,核心其實都是基於grid的shape cast。3、path caching
不用每個單位每次尋路都做A*。大部分時候都很容易找到可以重用的path。
另外RVO吧,我感覺就是移動過程中會整齊自然點,對解決RTS中更常見的一些問題其實並沒有那麼神奇。當然,去掉碰撞的話問題會簡化一個級別。看下Profiler熱點在哪裡,光從演算法上來說看起來沒有什麼原則性的問題
子彈穿透這個我反而覺得索性讓它穿,或者做兩套Update/FixedUpdate,部分高頻刷新
lua/c#交互可以看下這個分享 用好Lua+Unity,讓性能飛起來--Lua與C#交互篇 - Blog
首先不知道你說的moba是不是標準的lol玩法的moba類型(當然也可能是cr類型的),這裡先根據你描述到指向性技能來假設是lol玩法的
畢竟很多優化,必須針對特定的遊戲設計,才能有特定的高效方案
1.尋路/AI
moba尋路的優化空間絕對是很大的,首先無論lol還是cr的小兵,就算要做到單兵有阻擋(沒阻擋的話就更簡單了),用a*持續尋路都是沒有必要的,先判斷直線連通,然後邊緣尋路,再不行才考慮A*且有距離限制,這種上古時代的尋路手法已經可以應付小兵尋路的情況(想想紅警1那時的運算能力),這將大大減少你所需的運算量2.AI
moba的小兵ai也比較簡單,見面互相擼,附近有玩家互懟就擼玩家,這裡可以進行高度的優化,來節省很多每幀的更新判斷(例如事件觸發)。題外話,lol如果你斷網了你甚至可能看到整個世界停了但是小兵還在互相扔技能,說明小兵只要有一個目標,剩下就是反覆播技能動畫,中間很多事情都可以忽略。3.lua語言的使用上
核心的高消耗運算,用lua實現當然是不合理的,尋路、碰撞甚至AI都可以用c#或者c++實現當然這裡存在一個很大的難題是主流的lua/c#交互方案性能確實不高,這裡有兩種思路3.1高頻交互的東西,用c++而不是c#,這能為你帶來很好的性能,因為lua跟c++交互的性能還算不錯,但是對於unity這樣的引擎,你的調試難度會高很多,你可能需要有一個精心維護的c++工程去持續維護這塊代碼。
3.2用c#和c++混合實現,但對lua只暴露c#的介面,c++只實現最穩定的演算法(比如尋路、碰撞),c#實現經常修改的遊戲邏輯但是又對性能敏感的內容。這能收穫c++的高性能,又能兼顧比較好的調試性以及便於做熱更新。但是這需要你精心設計lua和c#以及c#與c++交互的部分,避免每幀多次交互(比如lua告訴底層開始移動,移動就交給底層持續自己更新就好),這樣才能規避掉交互上的性能損失。如果這塊沒做好,交互上的性能損失會大得誇張。可以看 @錢康來轉的那篇關於lua/c#交互的4.子彈
首先,跟策劃確定一下是不是真的所有子彈要全方向性(相信我,絕對沒必要),就算是lol也不是所有都是,起碼小兵是鎖定性這一點就已經讓子彈的判定不再是性能瓶頸(畢竟10個玩家使用技能的頻率就那麼點)高速子彈穿牆的問題,主流解決思路就是加大頻率或者使用直線相交,後者網上有很多介紹5.更新頻率遊戲邏輯每個part的更新頻率可以有很大的差異,比如移動是最敏感的,可以高頻更新;小兵AI、buff是次要的,可以500ms一更都可以;要立即產生反應的,走事件觸發。具體看你們遊戲的需求profiler找熱點,先優化最費的系統。估計要麼就是尋路,要麼就是ai。不是每幀必須跑的邏輯可以間隔幾幀跑。同理不是每幀必須跑的ai可以間隔幾幀跑,不過這樣會加大系統複雜度...
聯網moba的尋路在手機端?網遊基本不這麼做...
大部分邏輯都不應該用lua寫,就像war3編輯器能編輯的部分放到lua,剩下的全都用c#完成。邏輯幀數那麼低肯定是有大量GC
優化cpu,dc。可以用c++
給個小建議 不一定適用針對每個模塊 做個性能測試(統計單位時間內的耗時) 然後就可以討論哪個模塊可以優化了
對於高速小物體穿透問題,unity自帶的碰撞檢測可以設置成連續碰撞檢測,不過題主自己也要多次測試,詳見Xylitogum的回答。
劍與家園,500個獨立AI也沒啥事
profile下,看耗在哪裡。遊戲邏輯沒有那麼耗的
參考王者榮耀
推薦閱讀:
※俯視角2D遊戲該如何表現角色多個方向的動作?
※2016 年你心目中的最佳獨立遊戲是哪些?
※如何自學遊戲製作?
※遊戲實際畫面如何能做成和遊戲CG一樣的效果?
※未來主機遊戲是否是繼手游之後另一個新的爆發點?