項目中場景需要一天二十四小時,用到了Time of day插件這裡就不講這個插件的用法了。
Google到一篇文章 http://wiki.unity3d.com/index.php/LightMapSwitcher拿來測試,發現可以用。准備把代碼直接放到項目中發現有個不是問題的問題
using UnityEngine;
using UnityEditor;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
//為什麼要用[System.Serializable]來序列化,而不是using System然後直接[Serializable]
//是應為對下面 <T>as object 有影響
//這裡序列化是為了在inspecter面板中可以編輯
[System.Serializable]
public class U_P_D{
//存放lightmaps的路徑,如我的存放在 Assets下的001文件夾你只需輸入001,如果是Assets-Scence-Main,那就輸入Scence/Main
public string _URL;
public string URL{
get {return _URL;}
set {_URL=value;}
}
//後綴名 lightmaps後綴名是 .exr
public string _Pattern;
public string Pattern{
get {return _Pattern;}
set {_Pattern=value;}
}
//dir 還是 light 即 是遠景還是近景 其中dir是lightmapNear,light是lightmapFar
public string _Distance;
public string Distance{
get {return _Distance;}
set {_Distance=value;}
}
}
[System.Serializable]
public class ALLNF{
[System.NonSerialized]
public Texture2D[] NF;
}
[System.Serializable]
public class AllLightMap{
[System.NonSerialized]
public LightmapData[] LM;
}
public class CC_LightMapSwitcher : MonoBehaviour {
//不知道你們遇到過lightmaps之後只有light.exr,沒有dir.exr,所以這裡我加了個判斷
//一切為了懶
public bool _Switchs;
public U_P_D[] _UPDs;
public List<ALLNF> _AllNFs;
public List<AllLightMap> _AllLFs;
void Start ()
{
SelectSelf ();
//然後將裡面的lightmaps排序
for (int i = 0; i < _AllNFs.Count; i++) {
_AllNFs[i].NF = _AllNFs[i].NF.OrderBy(t2d => t2d.name, new NaturalSortComparer<string>()).ToArray();
}
//如果你打鉤表示你的lightmaps有dir和light兩種
if (_Switchs) {
for (int AllLFs_i = 0; AllLFs_i < _AllLFs.Count; AllLFs_i++) {
int AllNFs_i=AllLFs_i*2;
_AllLFs[AllLFs_i].LM= new LightmapData[_AllNFs[AllNFs_i].NF.Length];
for (int i=0; i<_AllNFs[AllNFs_i].NF.Length; i++)
{
_AllLFs[AllLFs_i].LM[i] = new LightmapData();
_AllLFs[AllLFs_i].LM[i].lightmapNear = _AllNFs[AllNFs_i].NF[i];
_AllLFs[AllLFs_i].LM[i].lightmapFar = _AllNFs[AllNFs_i+1].NF[i];
}
}
} else {
for (int AllLFs_i = 0; AllLFs_i < _AllLFs.Count; AllLFs_i++) {
//int AllNFs_i=AllLFs_i*2;
_AllLFs[AllLFs_i].LM= new LightmapData[_AllNFs[AllLFs_i].NF.Length];
for (int i=0; i<_AllNFs[AllLFs_i].NF.Length; i++)
{
_AllLFs[AllLFs_i].LM[i] = new LightmapData();
//_AllLFs[AllLFs_i].LM[i].lightmapNear = _AllNFs[AllLFs_i].NF[i];
_AllLFs[AllLFs_i].LM[i].lightmapFar = _AllNFs[AllLFs_i].NF[i];
}
}
}
}
#region SelectSelf
public void SelectSelf(){
if (_UPDs.Length==_AllNFs.Count) {
for (int i = 0; i < _UPDs.Length; i++) {
_AllNFs[i].NF=LoadAsset<Texture2D> (_UPDs[i].URL, _UPDs[i].Pattern, _UPDs[i].Distance);
}
}
}
T[] LoadAsset<T>(string path, string pattern,string Distance) where T : Object
{
string objPath = Application.dataPath + "/" + path;
string[] directoryEntries;
List<T> objList = new List<T>();
try
{
directoryEntries = System.IO.Directory.GetFileSystemEntries(objPath);
for (int i = 0; i < directoryEntries.Length; i++)
{
string p = directoryEntries[i];
string[] tempPaths = SplitWithString(p, "/Assets/"+path+"\\");
if (tempPaths[1].EndsWith(Distance + "." + pattern))
{
if (!tempPaths[1].StartsWith("ReflectionProbe")) {
T tempTex = AssetDatabase.LoadAssetAtPath("Assets/"+path+"/" + tempPaths[1], typeof(T)) as T;
if (tempTex != null){
objList.Add(tempTex);
}
}
}
}
}
catch (System.IO.DirectoryNotFoundException)
{
Debug.Log("The path encapsulated in the " + objPath + "Directory object does not exist.");
}
if (objList.Count > 0)
return objList.ToArray();
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();
}
#endregion
#region Publics
public void SetToDay()
{
//這裡與源代碼不同
LightmapSettings.lightmaps = _AllLFs[0].LM;
}
public void SetToNight()
{
LightmapSettings.lightmaps = _AllLFs[1].LM;
}
#endregion
#region Debug
[ContextMenu ("Set to Night")]
void Debug00()
{
SetToNight();
}
[ContextMenu ("Set to Day")]
void Debug01()
{
SetToDay();
}
#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; } }
用法 順序反著說好理解
1.Switchs打鉤就是有dir和light ,只有一種就取消
2.AllLFs 表示你有幾套貼圖,我這只用到兩套白天黑夜,可以多套,下面就要相對應的改變參數
3.AllNFs 和UPDs長度一致 如果Switchs打鉤 表示AllLFS一套中有分近景和遠景兩種,長度就是AllLFS的兩倍。Switchs不打鉤,長度與AllLFS一致。
4.UPDs 中URL表示lightmaps路徑
Pattern為後綴名
Distance為遠近景
代碼有注釋
親測可用。因為我這裡只是用到兩套貼圖,所以點擊事件就寫的白天和黑夜兩種,如果貼圖有十多套完全可以代碼控制。這裡就不寫了。
還有這個代碼適合靜態場景物體貼圖替換,場景動態物體中貼圖替換現在沒考慮。 不過我看到雨松MOMO博客中有一個關於動態替換的,大家可以搜索看看。
想各位大神提出意見,看看我的代碼是不是還有什麼問題,或者有改進的地方。