關於 web service, unity, blogger 等軟體工程筆記

Unity AssetBundle 載入後,出現粉紅色區塊的問題與解決

Edit icon 沒有留言
粉紅色塊示意圖,左邊為正常的 Unity Chan,右邊因 Shader 載入錯誤導致粉紅頭髮

Model is Unity Chan.

之前遇到的問題,當遊戲採用 AssetBundles 機制加載場景資源後,會發現有些場景問題變成粉紅色的,記錄問題以及解決方案。

Note: 使用版本 Unity5.5.x

粉紅色的色塊

遊戲因為動態更新以及手機平台上架需求,將部份資源打包成 AssetBundles,在遊戲執行階段加載該些 AssetBundles 來使用,在 Editor 測試一切正常,但移到手機上執行便出現有粉紅色的色塊 (pink) 的問題,如首圖右邊 Unity Chan 的頭髮區塊。

由過去的經驗以及問題的尋找發現,這是因為 Shader 載入錯誤才會出現粉紅色,載入錯誤可能是 Shader 編譯錯誤或者是遊戲中沒有該 Shader

在我們遊戲的例子中,是因為包成 AssetBundles 後,Unity Shader Stripped 機制,沒有把該 Shader 打包進遊戲 APP 中,導致載入 AssetBundles 後,裡頭材質球 (Material) 沒有辦法找到一開始指定的 Shaders,所以變成粉紅色了。

解決方式

  1. MenuItem > Editor > Project Settings > Graphics 開啟設定
    Unity Graphics Settings,預設有 6 項 Shaders 被加入

    Unity Graphics Settings,預設有 6 項 Shaders 被加入

  2. 將有使用到的 Shaders 填入到 Always Included Shaders,確保遊戲 APP 發佈有該些 Shaders
  3. 重新建置遊戲專案,Done!

尋找專案使用到的 Shaders

問題是怎麼知道專案用到那些 Shaders?美術自己可能也不清楚當初他們怎麼弄的。因此我們自己寫了小小的 Scripts,來查訪 Editor 模式中到底載入那些 Shaders,進而篩選真正有使用到的 Shaders,再放入 Always Included Shaders 中。

使用方式是在 Editor 中進行遊戲 (PlayMode),遊戲過程中執行該 Script,會列出目前編輯器所載入的 Shaders。

[MenuItem("Tools/List Shaders")]
static void ListEditorShaders()
{
   var shaders = new List<Shader>();
   var mats = Resources.FindObjectsOfTypeAll<Material>();
   foreach (var mat in mats)
   {
      if (!shaders.Contains(mat.shader) && mat.shader.name.IndexOf("Hidden/") != 0)
      {
         shaders.Add(mat.shader);
      }
   }
   foreach (var shader in shaders)
   {
      Debug.Log(shader.name);
   }
}

踩雷心得,注意不要一股腦將所有列出來的 Shaders 放到 Always Included Shaders,因為有些 Shaders 寫法很舊,可能會造成輸出的所有 Shaders 沒有辦法編譯,導致整個畫面全部變成粉紅色的…。

Reference

沒有留言: