The 15th expansion of Unity editor: NGUI mass replacement atlas tool

NGUI batch replace atlas tool

Tool purpose

Because the project needs to realize the skin changing function, i.e. multiple sets of UI atlas, provide tools to change atlas in batches, so as to view the effect under each skin (Atlas) of Prebab conveniently

Sketch Map

Gif operation diagram:

Tool screenshot:

On the left side of the tool is the list of all Prefab in the project, and on the right side is the function menu of the replacement atlas, replacing the specified original atlas with the target atlas

logic

And above: Unity editor 14: font replacement tool https://blog.csdn.net/qq_26999509/article/details/81106083 In fact, find all uisprites under Prebfab, and replace all the specified original atlas with the specified target atlas to realize the skin changing function. Of course, the spritene names of the two atlas should be consistent, otherwise, there is no way to know the one in the target atlas to be replaced.

Key code

private void ReplacePrefabAtalas(GameObject prefab , UIAtlas atlas,UIAtlas targetAtlas)
{
    if(prefab == null || atlas == null) return;
    UISprite[] sprites = prefab.GetComponentsInChildren<UISprite>(true);
    if(sprites != null && sprites.Length > 0)
    {
        int num = sprites.Length;
        for (int i = 0; i < num; i++)
        {
            UISprite s = sprites[i];
            if(s != null && s.atlas == atlas)
            {
                s.atlas = targetAtlas;
                EditorUtility.SetDirty(s);
            }
        }
    }
    AssetDatabase.SaveAssets();
}

Use

1. Tools - > replaceatalas open tools

2. Select the prefab to be processed, right click - > replace Atlas

3,

4,

Tool code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using UnityEditor.IMGUI.Controls;

public class ReplaceAtalas : EditorWindow 
{

    private static ReplaceAtalas window = null;
    private static List<string> prefabPathList = new List<string> ();
    private static string assetPath;

    Rect SearchFieldRect
    {
        get
        {
            return new Rect(interval,interval,position.width * 0.3f,20f);
        }
    }

    Rect prefabListRect 
    {
        get { return new Rect (interval, interval + SearchFieldRect.yMax, SearchFieldRect.width, window.position.height - SearchFieldRect.yMax - 2 * interval); }
    }

    Rect replaceAtalsRect
    {
        get{return new Rect(prefabListRect.xMax + interval,interval,window.position.width - SearchFieldRect.width - 3 * interval,window.position.height - 2 * interval);}
    }

    private Vector2 scrollWidgetPos;
    private float interval = 20f;
    private string searchStr = "";
    private SearchField searchField;
    private bool initialized = false;

    [MenuItem("Assets/Replacement Atlas", false, 2001)]
    public static void OpenWindow()
    {
        string selectedAssetPath = AssetDatabase.GetAssetPath (Selection.activeObject);
        if(!string.IsNullOrEmpty(selectedAssetPath) && selectedAssetPath.EndsWith(".prefab"))
        {
            ReplaceAtalas window = ShowWindow();
            if(window != null)
            {
                window.AutoSelctPrefab(selectedAssetPath);
            }
        }
    }

    [MenuItem("Tools/ReplaceAtalas")]
    public static ReplaceAtalas ShowWindow() 
    {
        prefabPathList.Clear ();
        assetPath = Application.dataPath;
        GetFiles (new DirectoryInfo (assetPath), "*.prefab", ref prefabPathList);
        if (window == null)
            window = EditorWindow.GetWindow(typeof(ReplaceAtalas)) as ReplaceAtalas;
        window.titleContent = new GUIContent("ReplaceAtalas");
        window.Show();
        return window;
    }

    public static void GetFiles (DirectoryInfo directory, string pattern, ref List<string> fileList) 
    {
        if (directory != null && directory.Exists && !string.IsNullOrEmpty (pattern)) {
            try {
                foreach (FileInfo info in directory.GetFiles (pattern)) {
                    string path = info.FullName.ToString ();
                    fileList.Add (path.Substring (path.IndexOf ("Assets")));
                }
            } catch (System.Exception) 
            {
                throw;
            }
            foreach (DirectoryInfo info in directory.GetDirectories ()) 
            {
                GetFiles (info, pattern, ref fileList);
            }
        }
    }

    private void OnGUI() 
    {
        InitIfNeeded();
        DrawWindow();
    }

    private void DrawWindow()
    {
        DrawSearchField();
        DrawPrefabList();
        DrawReplaceAtalasTool();
    }

    private void InitIfNeeded()
    {
        if(!initialized)
        {
            if (null == searchField)
                searchField = new SearchField ();
        }
        initialized = true;
    }

    private void DrawSearchField()
    {
        GUI.backgroundColor = Color.white;
        searchStr = searchField.OnGUI (SearchFieldRect, searchStr);
        searchStr = searchStr.ToLower();
    }

    private void DrawPrefabList()
    {
        GUI.backgroundColor = Color.white;

        GUI.Box(prefabListRect,"");
        GUILayout.BeginArea(prefabListRect);
        scrollWidgetPos = EditorGUILayout.BeginScrollView(scrollWidgetPos);
        for (int i = 0; i < prefabPathList.Count; i++)
        {
            if(CheckShowPrefab(prefabPathList[i],searchStr))
            {
                if(GUILayout.Button(prefabPathList[i]))
                {
                    curReplacePrefabPath = prefabPathList[i];
                    curPrefabAtlas = GetPrefabAllAtlas(curReplacePrefabPath);
                }
            }
        }
        EditorGUILayout.EndScrollView();
        GUILayout.EndArea();
    }

    private string curReplacePrefabPath = "";

    private bool CheckShowPrefab(string path,string searchstr)
    {
        if(string.IsNullOrEmpty(searchStr)) return true;
        if(string.IsNullOrEmpty(path)) return false;
        return GetFileNameWithSuffix(path.ToLower()).Contains(searchStr);
    }

    //Include suffix
    private string GetFileNameWithSuffix(string path)
    {
        if(string.IsNullOrEmpty(path)) return string.Empty;
        return path.Substring(path.LastIndexOf("/")+1);
    }

    private UIAtlas curAtlas;
    private UIAtlas targetAtlas;

    void OnSelectAtlas (Object obj)
    {
        UIAtlas atlas = obj as UIAtlas;
        if(isSelectCurAtlas)
        {
            curAtlas = obj as UIAtlas;
        }
        else if(isSelectTargetAtlas)
        {
            targetAtlas = obj as UIAtlas;
        }
        isSelectCurAtlas = false;
        isSelectTargetAtlas = false;
    }

    private bool isSelectCurAtlas = false;
    private bool isSelectTargetAtlas = false;
    private List<UIAtlas> curPrefabAtlas = new List<UIAtlas>();
    private void DrawReplaceAtalasTool()
    {
        GUI.backgroundColor = Color.white;

        GUILayout.BeginArea(replaceAtalsRect);
        EditorGUILayout.LabelField(curReplacePrefabPath);

        GUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("All atlas contained in the prefabrication:",GUILayout.Width(150));
        if(curPrefabAtlas.Count > 0)
        {
            for (int i = 0; i < curPrefabAtlas.Count; i++)
            {
                if(GUILayout.Button(curPrefabAtlas[i].name))
                {
                    curAtlas = curPrefabAtlas[i];
                }
                if(GUILayout.Button("Edit"))
                {
                    //NGUISettings.atlas = mFont.atlas;
                    //NGUISettings.selectedSprite = sym.spriteName;
                    NGUIEditorTools.Select(curPrefabAtlas[i].gameObject);
                }
            }
        }
        GUILayout.EndHorizontal();

        //Original Atlas
        GUILayout.BeginHorizontal();
        curAtlas = (UIAtlas)EditorGUILayout.ObjectField("Replaced Atlas", curAtlas, typeof(UIAtlas), true);
        if (NGUIEditorTools.DrawPrefixButton("Choice Atlas",GUILayout.Width(200)))
        {
            isSelectCurAtlas = true;
            ComponentSelector.Show<UIAtlas>(OnSelectAtlas);
        }
        GUILayout.EndHorizontal();

        //Target Atlas
        GUILayout.BeginHorizontal();
        targetAtlas = (UIAtlas)EditorGUILayout.ObjectField("Target Atlas", targetAtlas, typeof(UIAtlas), true);     

        if (NGUIEditorTools.DrawPrefixButton("Choice Atlas",GUILayout.Width(200)))
        {
            isSelectTargetAtlas = true;
            ComponentSelector.Show<UIAtlas>(OnSelectAtlas);
        }
        GUILayout.EndHorizontal();

        if(GUILayout.Button("Exchange"))
        {
            UIAtlas tmpCurAtlas = curAtlas;
            curAtlas = targetAtlas;
            targetAtlas = tmpCurAtlas;
        }

        //Replace button
        if(GUILayout.Button("Replacement Atlas"))
        {
            if(string.IsNullOrEmpty(curReplacePrefabPath))
            {
                EditorUtility.DisplayDialog("Tips", "Please select a prefab first!", "Determine");
            }
            else if (curAtlas == null)
            {
                EditorUtility.DisplayDialog("Tips", "Please specify the replaced atlas first!", "Determine");
            }
            else
            {
                if(targetAtlas == null)
                {
                    if(EditorUtility.DisplayDialog("Tips", "The original image set will be cleared. Are you sure you want to replace it?", "Determine","cancel"))
                    {
                        ReplacePrefabAtalas(curReplacePrefabPath);
                    }
                }
                else
                {
                    ReplacePrefabAtalas(curReplacePrefabPath);
                }
            }
        }
        //Save button

        //Cancel button

        GUILayout.EndArea();
    }

    private void ReplacePrefabAtalas(string path)
    {
        if(string.IsNullOrEmpty(path)) return;
        GameObject gameObj = AssetDatabase.LoadAssetAtPath<GameObject>(path);
        ReplacePrefabAtalas(gameObj,curAtlas,targetAtlas);
    }   

    private List<UIAtlas> GetPrefabAllAtlas(string path)
    {
        if(string.IsNullOrEmpty(path)) return null;
        GameObject gameObj = AssetDatabase.LoadAssetAtPath<GameObject>(path);
        return GetPrefabAllAtlas(gameObj);
    }

    private List<UIAtlas> GetPrefabAllAtlas(GameObject prefab)
    {
        if(null == prefab) return null;
        List<UIAtlas> atlass = new List<UIAtlas>();
        UISprite[] sprites = prefab.GetComponentsInChildren<UISprite>(true);
        if(sprites != null && sprites.Length > 0)
        {
            int num = sprites.Length;
            for (int i = 0; i < num; i++)
            {
                UISprite s = sprites[i];
                if(s != null && !atlass.Contains(s.atlas))
                {
                    atlass.Add(s.atlas);
                }
            }
        }
        return atlass;
    }

    private void ReplacePrefabAtalas(GameObject prefab , UIAtlas atlas,UIAtlas targetAtlas)
    {
        if(prefab == null || atlas == null) return;
        UISprite[] sprites = prefab.GetComponentsInChildren<UISprite>(true);
        if(sprites != null && sprites.Length > 0)
        {
            int num = sprites.Length;
            for (int i = 0; i < num; i++)
            {
                UISprite s = sprites[i];
                if(s != null && s.atlas == atlas)
                {
                    s.atlas = targetAtlas;
                    EditorUtility.SetDirty(s);
                }
            }
        }
        AssetDatabase.SaveAssets();
    }

    public void AutoSelctPrefab(string prefabPath)
    {
        if(string.IsNullOrEmpty(prefabPath)) return;
        curReplacePrefabPath = prefabPath;
        curPrefabAtlas = GetPrefabAllAtlas(curReplacePrefabPath);
        curAtlas = null;
        targetAtlas = null;
    }
}

Code Git address

https://github.com/JingFengJi/ReplaceAtlas
Welcome star

If there are any mistakes in the above knowledge sharing, please point out that we should learn together and make progress together.

Tags: Unity git github

Posted on Fri, 31 Jan 2020 10:53:51 -0500 by beaudoin