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
