轉載請標明出處:http://www.cnblogs.com/zblade/
一、概述
整理遇到的一些較難處理的bug,總結相關經驗
二、主要問題
2.1 material類型的依賴修改
對於material類型的asset,如果修改了其shader,對應的texture也修改了,並不會立刻刷新,從而導致以前的依賴的texture也會被打入到當前的ab依賴關系中。解決辦法,對於material類型,則通過EditorUtility.CollectDependencies 來剔除這種冗余的依賴,具體代碼示例:
if(isMat) { dependencies = AssetDatabase.GetDependencies(asset, false); UnityEngine.Object[] colDep = EditorUtility.CollectDependencies(new UnityEngine.Object[] { AssetDatabase.LoadAssetAtPath(asset, typeof(Material)) }); HashSet<string> filterd = new HashSet<string>(); foreach (var item in dependencies) { foreach (var item1 in colDep) { if (item.Contains(item1.name)) { filterd.Add(item); break; } } } dependencies = filterd.ToArray(); }
2.2 gitlab向jenkins推送的webhook,如何判斷其來自哪個分支
對於gitlab推送的webhook,需要判斷其來自哪個分支,從而切換打包機到指定的分支進行相關工作。在mac的環境下,可以通過特殊的操作獲取其推送的分支信息:
在每次gitlab推送信息到mac打包機的時候,當前mac的環境變量中有一個關鍵環境變量: gitlabTargetBranch,通過獲取該關鍵環境變量,可以得到對應的分支信息
--python 獲取方式 git_branch = os.getenv('gitlabTargetBranch')
2.3 lua虛擬機的重啟
在熱更新機制中,如果在熱更新完成后,需要重啟lua虛擬機,在xlua的機制下,需要注意,重啟lua虛擬機的操作,不能來自於lua端,只能是來自於c#端,也就是lua不能自己調用自己的重啟。
2.4 同步加載bundle和異步加載bundle的處理
在游戲中,啟動異步加載某個bundle的時候,如果后續有同步加載該bundle的操作觸發,需要打斷異步加載操作,可以通過異步加載操作直接獲取bundle的方式打斷異步,具體的示例代碼:
AssetBundleCreateRequest abRequest = AssetBundle.LoadFromFileAsync(path);
//這步操作,會直接獲取bundle,從而打斷異步加載操作 AssetBundle ab = abRequest.assetBundle; if (ab == null) { ab = AssetBundle.LoadFromFile(path); var assets = ab.LoadAllAssets(); foreach (var item in assets) { Debug.Log(item.name); } } else { var assets = ab.LoadAllAssets(); foreach(var item in assets) { Debug.Log(item.name); } }
2.5 場景bundle丟失lightmap(光照貼圖)的問題
在某些場景bundle中,已經將相關的lightmap打入bundle中,但是對應的實際運行時並沒有將相關的lightmap加載進來,用AssetStudio發現bundle中實際是有的。可能原因是bundle有,但是並沒有關聯。這時候需要修改unity的相關設置:
在Edit->Project Setting -> Graphics,找到 Shader Stripping, 將Lightmap modes從Automatic改成Custom, 勾選Baked Non-Directional,然后重新打bundle,編譯后的bundle就不會出現lightmap丟失的問題了
2.6 XLua基類拓展方法的坑
在xlua中,對基類拓展的實現:
首先,在c#端加上拓展實現:
namespace UnityEngine
{
[XLua.LuaCallCSharp]
public static class ExtMethodLua
{
public static void SetActive( this Component c, bool value)
{
c.gameObject.SetActive(value);
}
}
}
有哪些坑?
1)對於拓展的基類和其拓展類,均需要添加[XLua.LuaCallCSharp]的標簽
問題解決:在生成代碼的時候,如果對某個類型進行了拓展,也需要將該類型打上對應的標簽,不能只單獨給拓展類打標簽。
如果只給拓展類打標簽,則只會生成拓展類的wrap文件,不會生成基類的wrap文件,那么基類中就不會包含這個拓展方法,所以會出現找不到該方法的報錯。
2)不執行生成代碼,不帶標簽,反射不會執行拓展方法
在XLua中,lua和c#的交互,有兩種方式,一種是以wrap文件的方式,執行lazy加載,在交互的時候調用。
一種是反射的方式,那么為什么沒有wrap的時候,啟動反射的方式,會查找不到拓展類的拓展方法?
XLua自身在執行反射的時候,是修改了反射中對方法的獲取方式,需要標記為LuaCallCSharp/ ReflectionUse,才能被獲取到
2.7 健全的處理同步和異步的機制
由於游戲中既有同步加載操作,又有異步加載操作,異步加載操作又可能是多個同時觸發,需要進行粒度的控制,這就需要較為健全的處理同步和異步的機制。首先設定同步優先級更高,每當有同步操作到來的時候,如果有同樣的異步操作,需要打斷異步操作,直接執行同步操作。
此外多個異步操作排隊,造成第一個異步操作和最后一個異步操作的間隔較大,可能輪詢到最后一個異步操作的時候,最開始的環境已經變換,相關的依賴判斷需要再次判斷,否則會帶來隱藏bug.
2.8 局內戰斗相關問題
如何設計一個高效,易拓展,健全,魯棒性高的戰斗系統,是一個持續開發的過程。最佳的實現思路,是首先確定需要什么樣的表現效果,基於效果反推操作模式,基於操作模式,確定技能流程,從而確立整體的流程。
程序在實現的過程中,應該以表現方案為基准,進而設計相關的代碼架構,同時兼容拓展性,便於后期的需求變更。
如果要做邏輯和表現分離類型游戲,一定要嚴格把控邏輯與表現的耦合。邏輯端要做到完全自運行,不依賴任何表現端的數據,邏輯端只負責發送相關指令/調用API給表現層即可。
當然,實際的執行時候,表現端總會來干擾邏輯端的自運行,這時候就需要雙方做溝通,保持邏輯端的自封閉的基准下,解除耦合,讓表現端盡量自運行。
今天先寫到這兒,后續再更新