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 ListLightingDatas = new List (); 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 [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: IComparer<string>, IDisposable { private readonly bool isAscending; public NaturalSortComparer(bool inAscendingOrder = true) { this.isAscending = inAscendingOrder; } #region IComparer Members public int Compare(string x, string y) { throw new NotImplementedException(); } #endregion #region IComparer 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以上。