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

Unity 5.x动态加载光照信息(所有坑已踩)的相关文章

C# 动态加载程序集信息

在设计模式的策略模式中,需要动态加载程序集信息,本文通过一个简单的实例,来讲解动态加载Dll需要的知识点. 涉及知识点: AssemblyName类,完整描述程序集的唯一标识, 用来表述一个程序集. Assembly类,在System.Reflection命名空间下,表示一个程序集,它是一个可重用.无版本冲突并且可自我描述的公共语言运行时应用程序构建基块. Module类 表述在模块上执行反射,表述一个程序集的模块信息. Type类,在System命名空间下,表示类型声明:类类型.接口类型.数组

Unity中资源动态加载的几种方式比较

初学Unity的过程中,会发现打包发布程序后,unity会自动将场景需要引用到的资源打包到安装包里,没有到的不会跟进去.我们在编辑器里看到的Asset中的文件结构只是工作于编辑器环境下的,在游戏中unity会重新组织数据库.这是我们一定会遇到一个需求,即动态的加载我们自己的文件,而且想维护这个文件存储和加载的位置,并且是各种自定义的文件. 比如说你换装,需要动态从磁盘load一个模型,正常情况下如果这个模型没有被场景引用到,它都根本不会被打进安装包的.再比如说我想存储一个自己定义的配置的文件,想

Delphi中动态加载TreeView信息

unit Unit3; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, DB, ADODB, StdCtrls; type PNodeInfo=^TNodeInfo; TNodeInfo=record ID:string; FullName:string; Url:string; end; TForm3 = class(TFor

unity 3D里有两种动态加载机制

unity 3D里有两种动态加载机制: 一是Resources.Load: 一是通过AssetBundle: 其实两者本质上没有什么区别.Resources.Load就是从一个缺省打进程序包里的AssetBundle里加载资源,而一般AssetBundle文件需要你自己创建,运行时动态加载,可以指定路径和来源的.其实场景里所有静态的对象也有这么一个加载过程,只是Unity后台替你自动完成了. 1.    AssetBundles是什么? 在一些大型的网络游戏,或者加载比较多的一些场景时,如果要等

UNITY如何动态加载R素材?

Daydream/Unity技術: Unity动态加载R素材-- 使用ScriptableObject和AssetBoudle by 高煥堂 一.背景说明:   如果您还不熟悉R素材与A素材,请您参阅:Real素材的有机次序.   大约半年前,我为了想参与与HTC 的Vive X加速器计划而设计了<VR+医疗MRI行业平台>.<R素材>概念和名词也是我当时提出的.这样的<VR行业平台>架构也适合于建立特性产业的素材和App平台.例如,台湾的莺歌镇是陶瓷/琉璃设计小城,台

Unity的动态加载简单使用

Unity的动态加载简单使用Unity可以快速,轻量化的实现IOC,不用自已写类似反射代码来动态加载类或dll了使用Unity先要用nuget获取相关引用文件Unity可通过代码或config文件来配置要加动态加载的内容 使用示例 static void Main(string[] args) { Console.WriteLine("'Y' use Config Register Type,Otherwise use Code Register Type"); bool isUseC

Unity使用脚本进行批量动态加载贴图

先描述一下我正在做的这个项目,是跑酷类音游. 那么跑酷类音游在绘制跑道上的时候,就要考虑不同的砖块显示问题.假设我有了一个节奏列表,那么我们怎么将不同的贴图贴到不同的砖块上去呢? 我花了好几个小时才搞清楚里面的门路,且听我慢慢道来. 首先我们建立一个地图,在上面新建一个Empty Object,将所有的Road砖块全部划分到这个分组里. 效果图如下: 我们得到了一些预制块,接下来我们要将其染上色. 首先的问题是,我们怎么遍历这些砖块呢?很简单,用Tag.我们将所有的砖块打上一个特别的tag,"r

Unity 利用UGUI打包图集,动态加载sprite资源

今天做了一个UI界面,这个界面是好友界面,该界面上有若干个好友item. 需要对每个tem的头像对象(image)动态显示对应的头像.尝试利用UGUI的图集来加载,具体实现如下: 1.首先,需要知道SpriteAtlas的功能,可以保存一些关于要打包进去的sprite的设置.(详细参数设置的意义有待进一步研究),其中的Objects For Packing可以关联到需要打包进这个已创建图集的Sprite,或者文件夹,或者texture.目前这里的做法是关联到了文件夹. 2.此时,unity已经给

Unity学习笔记13——代码动态加载Prefab预设体

在进行一些功能开发的时候,我们常常将一些能够复用的对象制作成.prefab的预设物体,然后将预设体存放到Resources目录之下,使用时再动态加载到场景中并进行实例化.例如:子弹.特效甚至音频等,都能制作成预设体. 一.预设动态加载到场景: 一个预设体要能够通过代码控制在场景中进行显示,需要三个步骤,这里我们以动态加载怪物血条为例子分析一个常见的误区: 1.预设体资源加载: //加载预设体资源 GameObject hp_bar = (GameObject)Resources.Load("Pr