NGUI 圖集解包的實現

最近寫Demo的時候從網上找資源,發現了一個項目源碼,發現裏面的UI是用NGUI實現,圖片已經打包成了圖集,而原先的散圖已經被刪除了(確實在正常的項目中這些散圖被打包成圖集之後就沒用了,留在項目中白白增大包體)但是我希望拿到這些散圖,在我自己的項目中使用UGUI搭建UI。所以有了這個需求。

核心代碼不多,是取自NGUI中UIAtlasInspector中的代碼

圖中是代碼原文


我給封裝成了函數,便於調用:

/// <summary>
    /// 保存圖集中的圖片
    /// </summary>
    /// <param name="_atlas">圖片所在的圖集</param>
    /// <param name="_sprite">圖集中要保存的圖片名字</param>
    /// <param name="_path">要保存的路徑</param>
    public static void SaveSpriteAsTexture(UIAtlas _atlas, string _sprite, string _path)
    {
        UIAtlasMaker.SpriteEntry se = UIAtlasMaker.ExtractSprite(_atlas, _sprite);

        if (se != null)
        {
            byte[] bytes = se.tex.EncodeToPNG();
            System.IO.File.WriteAllBytes(_path, bytes);
            AssetDatabase.ImportAsset(_path);
            if (se.temporaryTexture)
                Object.DestroyImmediate(se.tex);
        }
    }

以這個函數爲核心,我實現了將整個圖集保存的函數,其核心原理是遍歷圖集中的所有圖片,然後調用上述函數進行保存,而在這個函數中我沒有設置開放性的路徑參數,這個可以根據實際應用進行修改。

/// <summary>
    /// 將圖集中的所有圖片拆分並保存
    /// </summary>
    /// <param name="_atlas">圖集</param>
    /// <param name="_refresh">是否立即更新</param>
    public static void CutTextures(UIAtlas _atlas, bool _refresh = true)
    {
        // 驗證參數有效性
        if (!_atlas) return;

        // 創建路徑
        if (!System.IO.Directory.Exists(Application.dataPath + "/AtlasTextures"))
        {
            AssetDatabase.CreateFolder("Assets", "AtlasTextures");
        }
        if (!System.IO.Directory.Exists(Application.dataPath + "/AtlasTextures/" + _atlas.name))
        {
            AssetDatabase.CreateFolder("Assets/AtlasTextures", _atlas.name);
        }


        // 開始
        var sprites = _atlas.GetListOfSprites();
        foreach(string spriteName in sprites)
        {
            string path = Application.dataPath + "/AtlasTextures/" + _atlas.name + "/" + spriteName + ".png";
            SaveSpriteAsTexture(_atlas, spriteName, path);
        }

        if (_refresh)
            AssetDatabase.Refresh();
    }

有了這兩個實現核心功能的函數,接下來就簡單了,只要在合適的時候調用即可,我再此處是點擊了菜單欄的相應項目後,獲取選中的所有圖集,然後遍歷保存:

[MenuItem("NGUI Sprite Unpacker/Sprite Unpacker")]
    static void Do()
    {
        string[] selectedAssets = Selection.assetGUIDs;
        if (selectedAssets == null || selectedAssets.Length == 0) return;
        foreach(string guid in selectedAssets)
        {
            UIAtlas atlas = LoadAssetByGUID<UIAtlas>(guid);
            CutTextures(atlas, false);
        }
        AssetDatabase.Refresh();
    }
其中,LoadAssetByGUID函數的實現如下:

這裏我將資源類型限制爲必須是Mono腳本,其實對於該函數來說不是必要的,通過實現可以看得出來,只要是繼承自UnityEngine.Object類的資源都可以

/// <summary>
    /// 根據GUID加載資源
    /// </summary>
    /// <typeparam name="T">要加載的資源的類型,該類型必須繼承MonoBehaviour</typeparam>
    /// <param name="_guid">資源的GUID</param>
    /// <returns>返回加載的資源,如果加載失敗將返回null</returns>
    static public T LoadAssetByGUID<T>(string _guid) where T : MonoBehaviour
    {
        string path = AssetDatabase.GUIDToAssetPath(_guid);
        T resum = AssetDatabase.LoadAssetAtPath(path, typeof(T)) as T;
        return resum;
    }

有了以上的實現之後,回到Unity編輯器,等到Unity將腳本更新完成,會發現菜單欄多了一條NGUI Sprite Unpacker,此時選中Project面板中的圖集,依次點擊菜單欄NGUI Sprite Unpacker ->Sprite Unpacker選項,然後鼠標會變成等待狀態(win7系統中是個藍色的圈一直在轉),等到鼠標還原時,就說明已經解包完成了,在Project面板中AtlasTextures文件夾下會發現以圖集名字命名的文件夾,裏面就是對應圖集的圖片了。

需要注意的是,上述代碼所在的腳本必須放到Editor文件夾下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章