Google到一篇文章 http://wiki.unity3d.com/index.php/LightMapSwitcher拿來測試,發現可以用。准備把代碼直接放到項目中發現有個不是問題的問題

這要自己一個一個拖拽,lightmaps少的話還可以,多了就好頭疼。
所以我就把代碼給改了,可能影響效率,畢竟多執行一些代碼,不可避免。不過方便很多。小項目可以用用。
第一個 CC_LightMapSwitch.cs
using UnityEngine; using System.Linq; using System.Text; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; [System.Serializable] public class Texture2Ds { public Texture2D[] LightMap; } internal class LightmapDatas { internal LightmapData[] LightData; } public class CC_LightMapSwitch : MonoBehaviour { public int LightingMapsIndex = 0; public Texture2Ds[] LightingMaps; private List<LightmapDatas> LightingDatas = new List<LightmapDatas> (); void Start () { if (LightingMaps.Length > 0) { for (int i = 0; i < LightingMaps.Length; i++) { LightmapDatas LtD = new LightmapDatas (); LightingDatas.Add (LtD); } for (int i = 0; i < LightingMaps.Length; i++) { Texture2D[] Near = LoadLightMapsAsset (LightingMaps [i].LightMap, "dir",i); Texture2D[] Far = LoadLightMapsAsset (LightingMaps [i].LightMap, "light",i); if (Near.Length != Far.Length) { Debug.Log ("LightingMaps[" + i + "]里的遠近貼圖不一致.dir的數量為:" + Near.Length + ",light的數量為:" + Far.Length + "."); return; } Near = Near.OrderBy (t2d => t2d.name, new NaturalSortComparer<string> ()).ToArray (); Far = Far.OrderBy (t2d => t2d.name, new NaturalSortComparer<string> ()).ToArray (); LightingDatas [i].LightData = new LightmapData[Near.Length]; for (int j=0; j<LightingDatas[i].LightData.Length; j++) { LightingDatas [i].LightData [j] = new LightmapData (); LightingDatas [i].LightData [j].lightmapNear = Near [j]; LightingDatas [i].LightData [j].lightmapFar = Far [j]; } } } } public Texture2D[] LoadLightMapsAsset (Texture2D[] texture, string Distance,int Idx) { //int len = texture.Length * 0.5; Texture2D[] objList = new Texture2D[texture.Length / 2]; try { int j = 0; for (int i = 0; i < texture.Length; i++) { string p = texture [i].name; if (p.EndsWith (Distance)) { objList [j] = texture [i]; j++; } } } catch (System.Exception ex) { Debug.Log ("加載LightingMaps["+Idx+"]的時候"+Distance+"為空"); } if (objList.Length > 0) return objList; return null; } public static string[] SplitWithString (string sourceString, string splitString) { string tempSourceString = sourceString; List<string> arrayList = new List<string> (); string s = string.Empty; while (sourceString.IndexOf(splitString) > -1) { //切割 s = sourceString.Substring (0, sourceString.IndexOf (splitString)); sourceString = sourceString.Substring (sourceString.IndexOf (splitString) + splitString.Length); arrayList.Add (s); } arrayList.Add (sourceString); return arrayList.ToArray (); } #region Publics public void setToLightmapDate (int Idx) { try { LightmapSettings.lightmaps = LightingDatas [Idx].LightData; } catch (System.Exception ex) { Debug.Log ("LightMapsIndex可能超過LightingMaps的界限或你的LightingMaps沒加載成功,錯誤:" + ex); } } #endregion #region Debug [ContextMenu ("Set to LightMaps")] void LightMapsInspactor () { setToLightmapDate (LightingMapsIndex); } #endregion }
第二個 NaturalSortComparer.cs 這個沒變
using UnityEngine; using System.Collections; using System; using System.Collections.Generic; using System.Text.RegularExpressions; public class NaturalSortComparer<T> : IComparer<string>, IDisposable { private readonly bool isAscending; public NaturalSortComparer(bool inAscendingOrder = true) { this.isAscending = inAscendingOrder; } #region IComparer<string> Members public int Compare(string x, string y) { throw new NotImplementedException(); } #endregion #region IComparer<string> Members int IComparer<string>.Compare(string x, string y) { if (x == y) return 0; string[] x1, y1; if (!table.TryGetValue(x, out x1)) { x1 = Regex.Split(x.Replace(" ", ""), "([0-9]+)"); table.Add(x, x1); } if (!table.TryGetValue(y, out y1)) { y1 = Regex.Split(y.Replace(" ", ""), "([0-9]+)"); table.Add(y, y1); } int returnVal; for (int i = 0; i < x1.Length && i < y1.Length; i++) { if (x1[i] != y1[i]) { returnVal = PartCompare(x1[i], y1[i]); return isAscending ? returnVal : -returnVal; } } if (y1.Length > x1.Length) { returnVal = 1; } else if (x1.Length > y1.Length) { returnVal = -1; } else { returnVal = 0; } return isAscending ? returnVal : -returnVal; } private static int PartCompare(string left, string right) { int x, y; if (!int.TryParse(left, out x)) return left.CompareTo(right); if (!int.TryParse(right, out y)) return left.CompareTo(right); return x.CompareTo(y); } #endregion private Dictionary<string, string[]> table = new Dictionary<string, string[]>(); public void Dispose() { table.Clear(); table = null; } }
不貼效果了,自行測試。還有這個代碼適合場景中靜態物體的貼圖替換(比如游戲中一開始就存在的房屋),場景中動態物體中貼圖替換現在沒考慮(比如游戲中動態加載的敵人之類的)。 不過我看到雨松MOMO博客中有一個關於場景中動態物體的貼圖如何替換,大家可以搜索看看。我不知道雨松MOMO 自己的代碼是否測試過50張貼圖以上的lightmaps ,我這里測試發現有問題,貼圖少的時候沒有問題,貼圖一多Unity程序直接崩潰,同時報一個錯然后你的工程就廢了,這個錯消不了,我用的是Unity5.2.2P,升級到Unity5.3.1就沒這種問題出錯的工程也不報那個錯,表示Unity5.2.2lightmaps有問題,大家要是替換多張貼圖最好是5.3.1以上。
