zoukankan      html  css  js  c++  java
  • Unity 预制体烘焙光影丢失,Unity2018 预制嵌套

    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 }
  • 相关阅读:
    xml转json
    3DES双倍长加密
    数据的集合运算
    SQL:1999基本语法
    表的连接操作
    数据库的连接
    表空间的创建
    用户的创建
    通用函数
    转换函数
  • 原文地址:https://www.cnblogs.com/roger634/p/9719739.html
Copyright © 2011-2022 走看看