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


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以上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM