Unity编辑器:搜索挂有UILocalize脚本的GamObject
发表于2018-07-19
本篇文章和大家介绍下如何实现指定文件夹(用鼠标选择Project目录下一个文件夹)下所有挂载UILocalize脚本的GameObject;
先说下怎么在Assets目录下搜索所有的prefab,代码如下:
<span style="font-family:SimSun;font-size:12px;"> /// <summary> /// 寻找所有类型的预制体 /// </summary> /// <returns></returns> public static Object[] Search() { string[] mExtensions = new string[] { ".prefab" }; string[] paths = AssetDatabase.GetAllAssetPaths(); BetterList<Object> list = new BetterList<Object>(); for (int i = 0; i < paths.Length; ++i) { string path = paths[i]; bool valid = false; for (int k = 0; k < mExtensions.Length; ++k) { if (path.EndsWith(mExtensions[k], System.StringComparison.OrdinalIgnoreCase)) { valid = true; break; } } if (!valid) continue; Object obj = AssetDatabase.LoadMainAssetAtPath(path); if (obj == null || list.Contains(obj)) continue; list.Add(obj); } EditorUtility.ClearProgressBar(); //if() return list.ToArray(); } </span>
关于AssetDatabase方法:
导入资源:
AssetDatabase.ImportAsset方法,Unity 只在需要时自动导入已拖放至该工程的资源,但也可能在脚本控制下导入这些资源。为此,您可以使用AssetDatabase.ImportAsset 类函数。您也可将额外的 AssetDatabase.ImportAssetOptions 类型参数传递至资源数据库 (AssetDatabase)
加载资源方法:
AssetDatabase.LoadAssetAtPath,AssetDatabase.LoadMainAssetAtPath,AssetDatabase.LoadAllAssetRepresentationsAtPath和AssetDatabase.LoadAllAssetsAtPath。
使用AssetDatabase 操作文件
Unity 将保留资源文件的元数据,您决不可使用文件系统创建、移动或删除它们。相反您可以AssetDatabase.Contains、AssetDatabase.CreateAsset、AssetDatabase.CreateFolder、AssetDatabase.RenameAsset、AssetDatabase.CopyAsset、AssetDatabase.MoveAsset、AssetDatabase.MoveAssetToTrash 和 AssetDatabase.DeleteAsset 进行相反上述操作
使用AssetDatabase.Refresh
修改完资源后,您应调用AssetDatabase.Refresh 将更改提交至数据库,并使其显示在工程中。
至于上面用到的AssetDatabase.GetAllAssetPaths(),不难看出是获取所有Assets下的路径,当然还有很多获取其他路径的方法,这里占时不写了。
但是需求改了要求搜索Scene/Hierarchy中所有挂载UILocalize脚本的GameObject,/(ㄒoㄒ)/~~好吧,不多说上代码:
<span style="font-family:SimSun;font-size:12px;"> /// <summary> /// 寻找场景中的GameObjec /// </summary> /// <returns></returns public static Object[] SearchScene() { GameObject[] pAllObjects = (GameObject[])Resources.FindObjectsOfTypeAll(typeof(GameObject)); BetterList<Object> list = new BetterList<Object>(); foreach (GameObject go in pAllObjects) { if (go.hideFlags != HideFlags.HideInHierarchy) { UnityEngine.Object parentObject = PrefabUtility.GetPrefabParent(go); string path = AssetDatabase.GetAssetPath(parentObject); Object obj = AssetDatabase.LoadMainAssetAtPath(path); if (obj == null || list.Contains(obj)) continue; if (!list.Contains(obj)) list.Add(obj); } } EditorUtility.ClearProgressBar(); return list.ToArray(); } </span>
搜索某个路径(填写一个路径)下所有挂载UILocalize脚本的GameObject:
<span style="font-family:SimSun;font-size:12px;"> // <summary> /// 搜索填写路径文件夹下的预制物体 /// </summary> /// <returns></returns> public static Object[] SearchFolder() { string[] mExtensions = new string[] { ".prefab" }; string[] paths = AssetDatabase.GetAllAssetPaths(); BetterList<Object> list = new BetterList<Object>(); for (int i = 0; i < paths.Length; ++i) { string path = paths[i]; if (path.Contains(_PathFolder)) { bool valid = false; for (int k = 0; k < mExtensions.Length; ++k) { if (path.EndsWith(mExtensions[k], System.StringComparison.OrdinalIgnoreCase)) { valid = true; break; } } if (!valid) continue; Object obj = AssetDatabase.LoadMainAssetAtPath(path); if (obj == null || list.Contains(obj)) continue; list.Add(obj); } } EditorUtility.ClearProgressBar(); return list.ToArray(); } </span>
代码跟搜索所有的物体差不多,只是加了个判断。
接下来是:指定文件夹(用鼠标选择Project目录下一个文件夹)下所有挂载UILocalize脚本的GameObject:
<span style="font-family:SimSun;font-size:12px;"> /// <summary> /// 搜索指定文件夹下的预制物体(与SearchFolder区别:此方法不需要填写路径,但是要:先在prproject目录下选择一个文件夹) /// </summary> /// <returns></returns> public static Object[] SearchMominateFolder() { var objs = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); EditorUtility.ClearProgressBar(); return objs; } </span>
代码很简单,5行搞定。
这里你会疑问,我怎么找啊?接下来我们写一个找的方法:
<span style="font-family:SimSun;font-size:12px;"> private void FindAllObj(System.Action<GameObject> mAction, SearchPath mType) { Info = string.Empty; Object[] allObj = null; switch (mType) { case SearchPath.Assets: allObj = Search(); break; case SearchPath.SceneAndHierarchy: allObj = SearchScene(); break; case SearchPath.PathFolder: allObj = SearchFolder(); break; case SearchPath.MominatePathFolder: allObj = SearchMominateFolder(); break; default: break; } if (allObj == null) return; _count = 0; _listPath.Clear(); _sts.Length = 0; //_sts.Append("列表:(更加详细的内容请参看项目根目录下PrefabUILocalize.txt)\n"); for (int i = 0; i < allObj.Length; i++) { if (PrefabUtility.GetPrefabType(allObj[i]) == PrefabType.Prefab) { GameObject _item_allObj = allObj[i] as GameObject; mAction(_item_allObj); } EditorUtility.DisplayProgressBar("资源分析中", "请耐心等候...", (float)i / allObj.Length); } _listPath.Sort(); for (int i = 0; i < _listPath.Count; i++) { _sts.AppendLine(string.Format("{0}.{1}", i + 1, _listPath[i])); } Info = _sts.ToString(); EditorUtility.ClearProgressBar(); EditorUtility.DisplayDialog("消息", string.Format("搜索分析完成,共搜索出相关物体{0}个,更加详细的内容请参看项目根目录下PrefabUILocalize.txt", _count.ToString()), "OK"); } /// <summary> /// 寻找挂有UILocalize脚本的预制物体 /// </summary> /// <param name="go"></param> protected virtual void FindUILocalize(GameObject go) { if (go.GetComponent<UILocalize>() != null) { _count++; string goName = go.name; Transform tf = go.transform; while (tf.parent != null) { goName = tf.parent.name + "/" + goName; tf = tf.parent; } _strTempInfo = string.Format("{0}/{1}", AssetDatabase.GetAssetPath(go), goName); if (!_listPath.Contains(_strTempInfo)) { _listPath.Add(_strTempInfo); } } foreach (Transform childTF in go.transform) { FindUILocalize(childTF.gameObject); } } </span>
但是需求又加了一条:要求写到一个文件里,代码如下。
<span style="font-family:SimSun;font-size:12px;">private void CreateFile(string info) { using (StreamWriter sw = new StreamWriter(@"PrefabUILocalize.txt")) { sw.Write(info); sw.Close(); sw.Dispose(); } } </span>
写完了,那该怎么应用到Unity呢?接下来就要用到using UnityEditor;
<span style="font-family:SimSun;font-size:12px;"> protected override void DarwInfo() { base.DarwInfo(); EditorGUILayout.BeginHorizontal(); _PathFolder = EditorGUILayout.TextField("请输入路径(区分大小写)", _PathFolder); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("寻找指定路径下挂载Localize脚本的预制体")) { FindAllObj(this.FindUILocalize, SearchPath.MominatePathFolder); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("寻找填写路径下挂载Localize脚本的预制体")) { FindAllObj(this.FindUILocalize, SearchPath.PathFolder); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("搜索场景中挂载Localize脚本的预制体")) { FindAllObj(this.FindUILocalize, SearchPath.SceneAndHierarchy); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("搜索Assets目录下挂载Localize脚本的预制体")) { FindAllObj(this.FindUILocalize, SearchPath.Assets); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("清空表中数据")) { Info = string.Empty; } EditorGUILayout.EndHorizontal(); } </span>
<span style="font-family:SimSun;font-size:12px;">using UnityEngine; using UnityEditor; using System.Collections; public class ToolsManager_OTT : Editor { [MenuItem("Tools_OTT/搜索含有UILocalize预制物体")] public static void ItemFindLocationInfo() { EditorWindow.GetWindow<FindUILocalizeObj_OTT>(false, "搜索含有UILocalize预制物体", true).Show(); } }</span>
最后效果:
来自:https://blog.csdn.net/nliki/article/details/51911878