Unity 5.x动态加载光照信息(所有坑已踩)

来源:互联网 发布:如何查看手机mac地址 编辑:程序博客网 时间:2024/06/05 22:57

能搜到这的应该是被新的烘焙系统坑了少时间,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.render18         data.SaveLightmap();19 20         EditorUtility.SetDirty(go);21         //applay prefab22         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_EDITOR16     [UnityEngine.SerializeField]17     Texture2D[] lightmapTexs;   //当前场景的灯光贴图18 #endif19 20     [UnityEngine.SerializeField]21     RendererInfo[] rendererList;22 23     #if UNITY_EDITOR24     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 #endif59 60 #if !UNITY_EDITOR61     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_EDITOR80         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         #endif97     }  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、最后一个坑就是不能完全相信搜索结果,他人记录的可能只是针对其出现的问题。