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

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

完成了匯入設定紋理,接下來我們要製作自己的配置檔案工具,需要製作一個編輯器視窗。

目前需求是兩個窗體,一個是配置列表介面;一個是配置介面。

因為要製作強制更新所以自身擴充套件兩個方法,一個是重新匯入某個路徑下所有資源,一個是獲取目錄下所有指定檔案格式檔案資訊。

 我們先擴充套件我們需要的方法。

實現GetFilesByExt方法

List<FileInfo> GetFilesByExt(DirectoryInfo rootDirInfo, params string[] param)
{
    List<FileInfo> list = new List<FileInfo>();
    foreach (var item in param)
    {
        list.AddRange(rootDirInfo.GetFiles(item, SearchOption.AllDirectories));
    }
    return list;
}

實現ReimportPath方法

void ReimportPath(string path, ImportAssetOptions option, params string[] param)
{
    if (!Directory.Exists(path))
        return;
    DirectoryInfo dirInfo = new DirectoryInfo(path);
    List<FileInfo> files = GetFilesByExt(dirInfo, param);
    for (int i = 0; i < files.Count; i++)
    {
        string apath = Application.dataPath.Replace('/', '\\');
        string filePath = files[i].FullName;
        AssetDatabase.ImportAsset(filePath.Substring(filePath.IndexOf(apath) + apath.Length - "Assets".Length), option);
    }
}

接下來我們只做主視窗類,偷懶所有繪製在一個裡面吧。先整合編輯器視窗

public class WinTextureImportSetting : EditorWindow
{
    
}

定義所需變數

        /// <summary>
        /// 紋理擴充套件字尾
        /// </summary>
        string[] textureExt = new string[] { "*.jpg", "*.png"};

        /// <summary>
        /// 視窗大小
        /// </summary>
        static Vector2 windowSize = new Vector2(400, 500);

        /// <summary>
        /// 視窗
        /// </summary>
        static WinTextureImportSetting window;

        /// <summary>
        /// 配置資料
        /// </summary>
        Dictionary<string, TextureImportConfig> ConfigDatas;
        /// <summary>
        /// 資料快取
        /// </summary>
        List<TextureImportConfig> CacheDatas;

新增入口

         [MenuItem("工具包/紋理配置介面")]
        static void Open()
        {
            window = GetWindow<WinTextureImportSetting>(WindowsTitle);
            window.position = new Rect(new Vector2(Screen.width / 2 - windowSize.x / 2, Screen.height / 2 - windowSize.y / 2), windowSize);
            window.minSize = windowSize;
        }

接下來繪製窗體。

/// <summary>
/// 當前編輯的配置
/// </summary>
TextureImportConfig EditorConfig;

void OnGUI()
{
    //繪製列表檢視,如果沒有編輯的物件
    if (EditorConfig == null)
    {
        DrawListView(CacheDatas);
    }
    else
    {
        DrawConfigView(EditorConfig);
    }
}

在我們實現繪製方法之前我們先只做一些針對資料的處理方法。

/// <summary>
/// 增加一個配置
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
string AddConfig(TextureImportConfig config)
{
    if (string.IsNullOrEmpty(config.TexturePath))
    {
        return "配置路徑不允許為Null!";
    }
    else if (ConfigDatas.ContainsKey(config.TexturePath))
    {
        return "配置路徑已經存在!";
    }
    else
    {
        ConfigDatas.Add(config.TexturePath, config);
        CacheDatas = ConfigDatas.Values.ToList();
        return null;
    }
}

/// <summary>
/// 移除一個配置
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
string RemoveConfig(TextureImportConfig config)
{
    if (config == null || string.IsNullOrEmpty(config.TexturePath))
    {
        return "沒有此配置資料!";
    }
    else if (!ConfigDatas.ContainsKey(config.TexturePath))
    {
        return "沒有此配置資料!";
    }
    else
    {
        ConfigDatas.Remove(config.TexturePath);
        CacheDatas = ConfigDatas.Values.ToList();
        return null;
    }
}

/// <summary>
/// 儲存配置
/// </summary>
void SaveConfig()
{
    string savePath = Application.dataPath + "/Editor Default Resources/" + TextureImportSetting.ConfigPath;
    string contents = JsonConvert.SerializeObject(ConfigDatas);
    if (!Directory.Exists(Path.GetDirectoryName(savePath)))
    {
        Directory.CreateDirectory(Path.GetDirectoryName(savePath));
    }
    File.WriteAllText(savePath, contents, System.Text.Encoding.UTF8);
    AssetDatabase.Refresh();
}

我們實現DrawListView

/// <summary>
/// 滑動層位置
/// </summary>
Vector2 scrollPosition;
/// <summary>
/// 繪製列表檢視
/// </summary>
/// <param name="configs"></param>
void DrawListView(List<TextureImportConfig> configs)
{
    //顯示資源根路徑;顯示新增路徑按鈕        
    GUILayout.BeginVertical();
    GUILayout.BeginHorizontal();
    GUILayout.Label("紋理生效目錄:"+ TextureImportSetting.DefaultPath);
    if (GUILayout.Button("+",GUILayout.MaxWidth(30))) { ClickAddPath(); }
    GUILayout.EndHorizontal();
    GUILayout.Label("配置檔案目錄:"+ TextureImportSetting.ConfigPath);           
    scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, true);
    GUILayout.Box("配置列表", GUILayout.ExpandWidth(true));
    if (configs != null)
    {
        for (int i = 0; i < configs.Count; i++)
        {
            DrawListElement(configs[i]);
        }
    }
    GUILayout.EndScrollView();
    GUILayout.EndVertical();
}

實現DrawListElement

/// <summary>
/// 繪製列表元素
/// </summary>
/// <param name="config"></param>
void DrawListElement(TextureImportConfig config)
{
    GUILayout.BeginVertical();
    GUILayout.Label("紋理路徑:" + config.TexturePath);
    GUILayout.BeginHorizontal();
    if (GUILayout.Button("修改配置", GUILayout.MaxWidth(80))) { ClickChangeConfig(config); }
    if (GUILayout.Button("刪除路徑", GUILayout.MaxWidth(80))) { ClickDeleteConfig(config); }
    if (GUILayout.Button("強更資源", GUILayout.MaxWidth(80))) { ClickReimport(config); }
    GUILayout.EndHorizontal();
    GUILayout.EndVertical();
}

實現點選方法

/// <summary>
/// 點選增加配置
/// </summary>
void ClickAddPath()
{
    EditorConfig = new TextureImportConfig();
    texturePath = "";
}
        
/// <summary>
/// 點選刪除配置
/// </summary>
/// <param name="config"></param>
void ClickDeleteConfig(TextureImportConfig config)
{
    string error = RemoveConfig(config);
    if (!string.IsNullOrEmpty(error))
    {
        EditorUtility.DisplayDialog("工具提示", error, "確定");
    }
    SaveConfig();
}
        
/// <summary>
/// 點選修改配置
/// </summary>
/// <param name="config"></param>
void ClickChangeConfig(TextureImportConfig config)
{
    if (ConfigDatas.ContainsKey(config.TexturePath))
    {
        texturePath = config.TexturePath;
        EditorConfig = config;
    }
}

/// <summary>
/// 點選強更資源
/// </summary>
/// <param name="config"></param>
void ClickReimport(TextureImportConfig config)
{
    TextureImportSetting.ClearConfig();
    ReimportPath(Application.dataPath + "/Editor Default Resources/" + config.TexturePath, ImportAssetOptions.Default, textureExt);
}

ok!基本上我們配置列表View已經搞定了!

接下來就是DrawConfigView介面

/// <summary>
/// 當前配置預設平臺
/// </summary>
PlatformEnum platform = PlatformEnum.Android;
/// <summary>
/// 繪製配置介面
/// </summary>
/// <param name="config"></param>
void DrawConfigView(TextureImportConfig config)
{
    GUILayout.BeginVertical();

    GUILayout.BeginHorizontal();
    if (GUILayout.Button("返回", GUILayout.MaxWidth(50))) { ClickReturn(); }
    if (GUILayout.Button("儲存", GUILayout.MaxWidth(50))) { ClickSave(); }
    GUILayout.EndHorizontal();

    GUILayout.BeginVertical();
    if (string.IsNullOrEmpty(config.TexturePath))
    {
        GUILayout.BeginHorizontal();
        GUILayout.Label("紋理目錄:", GUILayout.Width(80));
        texturePath = EditorGUILayout.TextField(texturePath, GUILayout.Height(20));
        GUILayout.EndHorizontal();
    }
    else
    {
        GUILayout.Label("紋理目錄:" + config.TexturePath);
    }
    GUILayout.Box("配置資料", GUILayout.ExpandWidth(true));

    GUILayout.BeginHorizontal();
    GUILayout.Label("紋理型別:", GUILayout.Width(100));
    config.TextureImporterType = (TextureImporterType)EditorGUILayout.EnumPopup(config.TextureImporterType);
    GUILayout.EndHorizontal();

    //TODO:你需要做的屬性設定

    GUILayout.EndVertical();
}

實現點選方法:點選返回會有個問題,不過對於我來說不是問題。就是當前我在修改某些屬性而未儲存,我在進入這個配置時資料會顯示修改後的狀態。因為我們的編輯配置是引用到的原資料,這個如果需要點返回修改的資料不儲存到配置列表裡,可以克隆配置類,然後儲存的時候替換給配置列表。

/// <summary>
/// 點選返回
/// </summary>
void ClickReturn()
{
    EditorConfig = null;
    texturePath = "";
}

/// <summary>
/// 點選儲存
/// </summary>
void ClickSave()
{
    if (!ConfigDatas.ContainsKey(texturePath))
    {
        EditorConfig.TexturePath = texturePath;
        string error = AddConfig(EditorConfig);
        if (!string.IsNullOrEmpty(error))
        {
            EditorUtility.DisplayDialog("工具提示", error, "確定");
        }
        else
        {
            SaveConfig();
            EditorUtility.DisplayDialog("工具提示", "儲存成功", "確定");
        }
    }
    else
    {
        SaveConfig();
        EditorUtility.DisplayDialog("工具提示", "儲存成功", "確定");
    }
}

到這裡編輯器就完事了!

最終我的效果圖是這個樣子的,因為程式碼有些多,所以很多程式碼需要讀者自己去補全。