程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> Unity5.x 動態加載lightmaps(烘培貼圖),unity5.xlightmaps

Unity5.x 動態加載lightmaps(烘培貼圖),unity5.xlightmaps

編輯:C#入門知識

Unity5.x 動態加載lightmaps(烘培貼圖),unity5.xlightmaps


項目中場景需要一天二十四小時,用到了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博客中有一個關於動態替換的,大家可以搜索看看。

 

想各位大神提出意見,看看我的代碼是不是還有什麼問題,或者有改進的地方。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved