Unity 5.x動態加載光照信息(所有坑已踩)


  能搜到這的應該是被新的烘焙系統坑了少時間,4.x到5.x美術必須重新烘焙,關於美術的沒什么說的,只有---重新烘焙!

  新的烘焙系統,為了兼容5.x的多場景編輯功能,將烘焙信息從mesh全部挪到了一個中間件xxx.assets,這個資源文件在5.x烘焙完成后和光照貼圖存放在一起,然而關於這個資源文件,我是查來查去沒有找到任何接口可以訪問。

  只能百度谷歌,發現方案基本都是序列化,因為上面提到的烘焙信息沒有在mesh中保存,而是一個雞肋資源文件,發布時xxx.assets可以刪了。

  序列化哪些數據,在編輯器面板能看到,在下面代碼中也能看到。

  編輯器腳本PrefabLightmapDataEditor.cs:

 1 using UnityEngine;  
 2 using UnityEditor;
 3 
 4 public class PrefabLightmapDataEditor : Editor {
 5     [MenuItem("Ojcgames Tools/保存該場景預制件的烘焙信息", false, 0)]
 6     static void SaveLightmapInfoByGameObject()  
 7     {  
 8         GameObject go = Selection.activeGameObject;
 9 
10         if(null == go)return;
11 
12         PrefabLightmapData data = go.GetComponent<PrefabLightmapData>();
13         if (data == null)
14         {
15             data = go.AddComponent<PrefabLightmapData>();
16         }
17         //save lightmapdata info by mesh.render
18         data.SaveLightmap();
19 
20         EditorUtility.SetDirty(go);
21         //applay prefab
22         PrefabUtility.ReplacePrefab(go, PrefabUtility.GetPrefabParent(go), ReplacePrefabOptions.ConnectToPrefab);
23     }
24 }

  被綁定在預制件父級上的序列化腳本PrefabLightmapData.cs:

 1 using UnityEngine;  
 2 using System.Collections;  
 3 using System.Collections.Generic;
 4 
 5 public class PrefabLightmapData : MonoBehaviour  
 6 {  
 7     [System.Serializable]
 8     struct RendererInfo  
 9     {  
10         public Renderer     renderer;  
11         public int          lightmapIndex;  
12         public Vector4      lightmapOffsetScale;  
13     }
14 
15 #if UNITY_EDITOR
16     [UnityEngine.SerializeField]
17     Texture2D[] lightmapTexs;   //當前場景的燈光貼圖
18 #endif
19 
20     [UnityEngine.SerializeField]
21     RendererInfo[] rendererList;
22 
23     #if UNITY_EDITOR
24     public void SaveLightmap()  
25     {
26         Renderer[] renders = GetComponentsInChildren<Renderer>(true);
27         RendererInfo rendererInfo;
28         rendererList = new RendererInfo[renders.Length];
29 
30         int index = 0;
31 
32         for(int r = 0, rLength = renders.Length; r<rLength; ++r)
33         {
34             if (renders[r].gameObject.isStatic == false) continue;
35 
36             rendererInfo.renderer = renders[r];
37             rendererInfo.lightmapIndex = renders[r].lightmapIndex;
38             rendererInfo.lightmapOffsetScale = renders[r].lightmapScaleOffset;
39 
40             rendererList[index] = rendererInfo;
41 
42             ++index;
43         }
44 
45         //序列化光照貼圖
46         LightmapData[] ldata = LightmapSettings.lightmaps;
47         lightmapTexs = new Texture2D[ldata.Length];
48         for(int t = 0, tLength = ldata.Length; t<tLength; ++t)
49         {
50             lightmapTexs[t] = ldata[t].lightmapFar;
51         }
52     }
53     
54     void Awake()
55     {
56         this.LoadLightmap();
57     }
58 #endif
59 
60 #if !UNITY_EDITOR
61     public 
62 #endif 
63     void LoadLightmap()
64     {
65         if(null == rendererList || rendererList.Length == 0)
66         {
67             Debug.Log(gameObject.name +  " 的 光照信息為空");
68             return;
69         }
70 
71         Renderer[] renders = GetComponentsInChildren<Renderer>(true);
72 
73         for(int r = 0, rLength = renders.Length; r<rLength; ++r)
74         {
75             renders[r].lightmapIndex = rendererList[r].lightmapIndex;
76             renders[r].lightmapScaleOffset = rendererList[r].lightmapOffsetScale;
77         }
78 
79         #if UNITY_EDITOR
80         if(null == lightmapTexs || lightmapTexs.Length == 0)
81         {
82             return;
83         }
84 
85         LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional;
86         LightmapData[] ldata = new LightmapData[lightmapTexs.Length];
87         LightmapSettings.lightmaps = null;
88 
89         for(int t = 0, tLength = lightmapTexs.Length; t<tLength; ++t)
90         {
91             ldata[t] = new LightmapData();
92             ldata[t].lightmapFar = lightmapTexs[t];
93         }
94 
95         LightmapSettings.lightmaps = ldata;
96         #endif
97     }  
98 }  

其中

Texture2D[] lightmapTexs;
Awake();
是我為了方便美術測試,發布項目中,我手動管理何時加載光照信息和光照貼圖,至此代碼已提供完。

下面說點碰到的坑:
1、PC正常,發布到android或ios完全看不到光照信息,並且序列化參數都正確,光照貼圖也加載正常,LightmapSettings.lightmapsMode = LightmapsMode.NonDirectional 設置正常:
  在發布時,Edit - Project Settings - Graphics - Shader Stripping - Lightmap modes - Manual
  關於該選項的官方說明:By default, Unity looks at your scenes and lightmapping settings to figure out which Fog and Lightmapping modes are used; and skips corresponding shader variants. This saves game build data size, and improves loading times.
  也就是說,如果你想用腳本動態的控制,那么就得將這里設置為手動模式。
2、最后一個坑就是不能完全相信搜索結果,他人記錄的可能只是針對其出現的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM