• 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、最后一个坑就是不能完全相信搜索结果,他人记录的可能只是针对其出现的问题。

  • 相关阅读:
    判断 undefined and ( == null) and (!something) and ( == null)
    textarea高度自适应自动展开
    退出 js和Jquery区别
    javascript高级程序设计 学习笔记 第五章 下
    Bind, Call and Apply in JavaScript
    javascript高级程序设计 学习笔记 第五章 上
    小程序入门---登录流程
    Array类型 JS
    深入浅出妙用 Javascript 中 apply、call、bind
    微信公众号开发(与angular框架相结合)
  • 原文地址:https://www.cnblogs.com/verlout/p/5734390.html
Copyright © 2020-2023  润新知