1. 程式人生 > >自動設定紋理資源屬性(一)

自動設定紋理資源屬性(一)

實際專案中,我們會對指定的紋理設定不同平臺不同屬性。手動去設定操作量相對較大特別是資源持續性迭代的情況下,所以為了目標需求,我們需要去製作一個工具來設定我們匯入的紋理資源。

目標1:獲取匯入的紋理資源,並修改紋理資源屬性。可用介面:AssetPostprocessor;TextureImporter。

目標2:製作編輯器。

 目標1實現:

熟悉AssetPostprocessor介面


public class TextureImportSetting : AssetPostprocessor
{
    /// <summary>
    /// 當一個材質賦值給渲染器時
    /// </summary>
    /// <param name="material">目標材質球</param>
    /// <param name="render">目標渲染器</param>
    void OnAssignMaterialModel(Material material, Renderer render) { }
    /// <summary>
    /// 匯入任何資源完成時呼叫,指資源讀取條完成後。
    /// </summary>
    /// <param name="importedAssets">匯入的資源列表</param>
    /// <param name="deletedAssets">刪除的資源列表</param>
    /// <param name="movedAssets">移動的資源列表</param>
    /// <param name="movedFromAssetPaths">移動到的資源列表</param>
    void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { }
    /// <summary>
    /// 當AB包的資源名稱發生變化時呼叫
    /// </summary>
    /// <param name="assetPath">路徑</param>
    /// <param name="previousAssetBundleName">之前資源名</param>
    /// <param name="newAssetBundleName">之後資源名</param>
    void OnPostprocessAssetbundleNameChanged(string assetPath, string previousAssetBundleName, string newAssetBundleName) { }
    /// <summary>
    /// 音訊資源完成匯入時
    /// </summary>
    /// <param name="clip">音訊資源</param>
    void OnPostprocessAudio(AudioClip clip) { }
    /// <summary>
    /// Cubemap 紋理完成匯入之前
    /// </summary>
    /// <param name="texture"></param>
    void OnPostprocessCubemap(Cubemap texture) { }
    /// <summary>
    /// 匯入的GameObject使用者屬性及其數值
    /// </summary>
    /// <param name="go">物件</param>
    /// <param name="propNames">使用者屬性名</param>
    /// <param name="values">屬性值</param>
    void OnPostprocessGameObjectWithUserProperties(GameObject go, string[] propNames, System.Object[] values) { }
    /// <summary>
    /// 材質球完成匯入時
    /// </summary>
    /// <param name="material">材質球</param>
    void OnPostprocessMaterial(Material material) { }
    /// <summary>
    /// 模型完成匯入時
    /// </summary>
    /// <param name="g">物件</param>
    void OnPostprocessModel(GameObject g) { }
    /// <summary>
    /// SpeedTree 完成匯入時
    /// </summary>
    /// <param name="g"></param>
    void OnPostprocessSpeedTree(GameObject g) { }
    /// <summary>
    /// Sprites 完成匯入時
    /// </summary>
    /// <param name="texture2D">紋理</param>
    /// <param name="sprites">圖片集</param>
    void OnPostprocessSprites(Texture2D texture2D, Sprite[] sprites) { }
    /// <summary>
    /// 紋理完成匯入時
    /// </summary>
    /// <param name="texture">紋理</param>
    void OnPostprocessTexture(Texture2D texture) { }
    /// <summary>
    /// 動畫匯入之前時
    /// </summary>
    void OnPreprocessAnimation() { }
    /// <summary>
    /// 匯入任何資源之前
    /// </summary>
    void OnPreprocessAsset() { }
    /// <summary>
    /// 音訊資源匯入之前
    /// </summary>
    void OnPreprocessAudio() { }
    /// <summary>
    /// 模型資源匯入之前
    /// </summary>
    void OnPreprocessModel() { }
    /// <summary>
    /// SpeedTree匯入之前
    /// </summary>
    void OnPreprocessSpeedTree() { }
    /// <summary>
    /// 紋理匯入之前
    /// </summary>
    void OnPreprocessTexture() { }
}

對於設定匯入的紋理屬性,我們只需要OnPreprocessTexture()回撥訊息即可。

我們需要AssetPostprocessor的兩個屬性一個是assetPath我們用於條件處理一個是assetImporter用於獲取當前設定物件。

定義需要處理的目錄結構

const string defaultPath = "/Editor Default Resources/";

由於框架模式已經固定。我的框架所有資源都是在Editor Default Resources。最終發包都是以AB包形式,編輯器狀態下都是直接在Editor Default Resources模式下直接讀取資源使用。

檢測當前紋理資源是否是需要處理資源,獲取當前資源紋理路徑的配置表。

public void OnPreprocessTexture()
{
    if(assetPath.IndexOf(defaultPath) >=0)
    {
        TextureImportConfig config = GetConfig(Path.GetDirectoryName(assetPath.Substring(assetPath.IndexOf(defaultPath) + defaultPath.Length)));
        TextureImporter impor = assetImporter as TextureImporter;
        if (impor!=null && config != null)
        {
            SetTextureImporter(impor,config);
        }
    }       
}

接下來實現獲取配置資料方法GetConfig。json反序列化我們用到了Newtonsoft.Json,請自行下載引用。

/// <summary>
/// 配置資料
/// </summary>
static Dictionary<string, TextureImportConfig> Configs;
/// <summary>
/// 清理配置資料
/// </summary>
public static void ClearConfig()
{
    Configs = null;
}
/// <summary>
/// 獲取配置資料
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public TextureImportConfig GetConfig(string path)
{
    if(Configs==null)
    {
        TextAsset confisFile = EditorGUIUtility.Load(configPath) as TextAsset;
        if(confisFile!=null)
        {
            Configs = JsonConvert.DeserializeObject<Dictionary<string, TextureImportConfig>>(confisFile.text);
        }
    }
    if(Configs!=null&&Configs.ContainsKey(path))
    {
        return Configs[path];
    }
    return null;
}

同樣我們需要定義我們的配置路徑。

const string configPath = "EditorConfig/TextureImportConfig.json";

接下來我們實現設定圖片資源屬性設定【SetTextureImporter】。

/// <summary>
/// 設定圖片匯入資料
/// </summary>
/// <param name="target"></param>
/// <param name="config"></param>
public void SetTextureImporter(TextureImporter target, TextureImportConfig config)
{
    target.textureType = config.TextureImporterType;
    //......
}

到此我們的目標1已經完成了,接下來我們開始擴充套件製作我們的編輯器。