您的位置:首页 > 移动开发 > Unity3D

Unity 预制体烘焙光影丢失,Unity2018 预制嵌套

2018-09-28 17:16 537 查看

Unity2018.3测试版发布后支持预制体嵌套……

问题:

1.unity场景烘焙后,再制作预制体后烘焙的光影丢失

2.如何将预制体的更改应用到各个子预制体

解决:

1.这个问题官方有解决,即是给每个需要加载的prefab添加PrefabLightmapData.cs脚本,但是这个脚本没有写完整,它只能在Non-Directional模式下可以正常工作,即没有加载Lightmap-_dir灯光贴图

2.在有嵌套的prefabs中,首先打开嵌套prefabs然后对各个子prefab执行applyAll操作,最后重新保存整个嵌套prefabs

3.本代码是在Unity2018.3.b3版本下编写的,部分api老版本有可能不一样(修改一下即可)

 

 

在官方代码基础上修改的代码如下:

 

1 using System.Collections;
2 using System.Collections.Generic;
3 using System.IO;
4 using UnityEditor;
5 using UnityEngine;
6 using VR403Works.Foundation.Extentions;
7
8 [DisallowMultipleComponent]
9 [ExecuteInEditMode]
10 public class PrefabLightmapData : MonoBehaviour
11 {
12
13     [System.Serializable]
14     struct RendererInfo
15     {
16         public Renderer renderer;
17         public int lightmapIndex;
18         public Vector4 lightmapOffsetScale;
19     }
20
21     [SerializeField]
22     RendererInfo[] m_RendererInfo;
23     [SerializeField]
24     Texture2D[] m_LightmapsColor;
25     [SerializeField]
26     Texture2D[] _lightmapsDir;
27
28     void Awake()
29     {
30         if (m_RendererInfo == null || m_RendererInfo.Length == 0)
31             return;
32
33         var lightmaps = LightmapSettings.lightmaps;
34         var combinedLightmaps = new LightmapData[lightmaps.Length + m_LightmapsColor.Length];
35
36         lightmaps.CopyTo(combinedLightmaps, 0);
37         for (int i = 0; i < m_LightmapsColor.Length; i++)
38         {
39             combinedLightmaps[i + lightmaps.Length] = new LightmapData();
40             combinedLightmaps[i + lightmaps.Length].lightmapColor = m_LightmapsColor[i];
41             combinedLightmaps[i + lightmaps.Length].lightmapDir = _lightmapsDir[i];
42
43         }
44
45         ApplyRendererInfo(m_RendererInfo, lightmaps.Length);
46         LightmapSettings.lightmaps = combinedLightmaps;
47     }
48
49
50     static void ApplyRendererInfo(RendererInfo[] infos, int lightmapOffsetIndex)
51     {
52         for (int i = 0; i < infos.Length; i++)
53         {
54             var info = infos[i];
55             if (info.renderer != null)
56             {
57                 info.renderer.lightmapIndex = info.lightmapIndex + lightmapOffsetIndex;
58                 info.renderer.lightmapScaleOffset = info.lightmapOffsetScale;
59             }
60         }
61     }
62
63 #if UNITY_EDITOR
64     [UnityEditor.MenuItem("VR403WorksTools/Bake Prefab Lightmaps")]
65     static void GenerateLightmapInfo()
66     {
67         if (UnityEditor.Lightmapping.giWorkflowMode != UnityEditor.Lightmapping.GIWorkflowMode.OnDemand)
68         {
69             Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled.");
70             return;
71         }
72         UnityEditor.Lightmapping.Bake();
73
74         PrefabLightmapData[] prefabs = GameObject.FindObjectsOfType<PrefabLightmapData>();
75
76         foreach (var instance in prefabs)
77         {
78             var gameObject = instance.gameObject;
79             var rendererInfos = new List<RendererInfo>();
80             var lightmapsColor = new List<Texture2D>();
81             List<Texture2D> lightmapsDir = new List<Texture2D>();
82
83             GenerateLightmapInfo(gameObject, rendererInfos, lightmapsColor, lightmapsDir);
84
85             instance.m_RendererInfo = rendererInfos.ToArray();
86             instance.m_LightmapsColor = lightmapsColor.ToArray();
87             instance._lightmapsDir = lightmapsDir.ToArray();
88
89
90             var targetPrefab = PrefabUtility.GetCorrespondingObjectFromOriginalSource(instance.gameObject) as GameObject;
91             if (targetPrefab != null)
92             {
93                 GameObject root = PrefabUtility.GetOutermostPrefabInstanceRoot(instance.gameObject);                        // 根结点
94                 //如果当前预制体是是某个嵌套预制体的一部分(IsPartOfPrefabInstance)
95                 if (root != null)
96                 {
97                     GameObject rootPrefab = PrefabUtility.GetCorrespondingObjectFromSource(instance.gameObject);
98                     string rootPath = AssetDatabase.GetAssetPath(rootPrefab);
99                     //打开根部预制体
100                     PrefabUtility.UnpackPrefabInstanceAndReturnNewOutermostRoots(root, PrefabUnpackMode.OutermostRoot);
101                     try
102                     {
103                         //Apply各个子预制体的改变
104                         PrefabUtility.ApplyPrefabInstance(instance.gameObject, InteractionMode.AutomatedAction);
105                     }
106                     catch { }
107                     finally
108                     {
109                         //重新更新根预制体
110                         PrefabUtility.SaveAsPrefabAssetAndConnect(root, rootPath, InteractionMode.AutomatedAction);
111                     }
112                 }
113                 else
114                 {
115                     PrefabUtility.ApplyPrefabInstance(instance.gameObject, InteractionMode.AutomatedAction);
116                 }
117             }
118         }
119     }
120
121     static void GenerateLightmapInfo(GameObject root, List<RendererInfo> rendererInfos, List<Texture2D> lightmapsColor, List<Texture2D> lightmapsDir)
122     {
123         var renderers = root.GetComponentsInChildren<MeshRenderer>();
124         foreach (MeshRenderer renderer in renderers)
125         {
126             if (renderer.lightmapIndex != -1)
127             {
128                 RendererInfo info = new RendererInfo();
129                 info.renderer = renderer;
130                 if (renderer.lightmapScaleOffset != Vector4.zero)
131                 {
132                     info.lightmapOffsetScale = renderer.lightmapScaleOffset;
133                     Texture2D lightmapColor = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapColor;
134                     Texture2D lightmapDir = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapDir;
135
136                     info.lightmapIndex = lightmapsColor.IndexOf(lightmapColor);
137                     if (info.lightmapIndex == -1)
138                     {
139                         info.lightmapIndex = lightmapsColor.Count;
140                         lightmapsColor.Add(lightmapColor);
141                         lightmapsDir.Add(lightmapDir);
142                     }
143
144                     rendererInfos.Add(info);
145                 }
146
147             }
148         }
149     }
150 #endif
151 }

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: