Unity3D 遍历预制体

Unity3D 遍历预制体进行批量化处理。

遍历预制体

有时候,我们需要对一些预制体资源进行批量化处理,如果每一个预制体都手动处理,就会耗费很多时间精力,也容易出错。

我们可以写一个脚本遍历预制体,对预制体进行修改,然后保存。

遍历文件路径

Editor 文件夹下创建一个脚本 TraverseAssets.cs,包含一个方法 TraversePrefab,加上 MenuItem 创建一个菜单栏按钮。

使用 Directory.GetFiles 方法,传入根目录的路径 path 和通配符 *.prefab,表示从 Assets 文件夹下获取所有以 .prefab 结尾的文件路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System.IO;
using UnityEngine;
using UnityEditor;

public class TraverseAssets
{
public static string path = "Assets/";

[MenuItem("搜索工具/遍历预制体")]
public static void TraversePrefab()
{
var allfiles = Directory.GetFiles(path, "*.prefab", SearchOption.AllDirectories);

foreach (var file in allfiles)
{
Debug.Log(file);
}
}
}

此时,菜单栏就有了搜索工具->遍历预制体按钮了。

点击按钮,可以看到控制台打印了预制体的路径信息。

接下来,根据路径信息,加载预制体。

使用 AssetDatabase.LoadAssetAtPath 方法,把路径传入,就可以得到一个 GameObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System.IO;
using UnityEngine;
using UnityEditor;

public class TraverseAssets
{
public static string path = "Assets/";

[MenuItem("搜索工具/遍历预制体")]
public static void TraversePrefab()
{
var allfiles = Directory.GetFiles(path, "*.prefab", SearchOption.AllDirectories);

foreach (var file in allfiles)
{
GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(file);
if (go)
{
Debug.Log(go.name);
}
}
}
}

再次点击菜单栏按钮,可以看到控制台打印的是已加载预制体的名称了。

修改预制体并保存

假设现在有个需求,搜索带有 SpriteRenderer 组件的预制体,把组件上的 Order in Layer 统一改成 100。

目前工程中,有两个预制体带有该组件,并且目标参数此时的值为 0。另外两个预制体没有该组件。

修改一下脚本,从加载出来的 GameObject 上获取 SpriteRenderer 组件,如果存在,则对 sortingOrder 进行修改,然后使用 PrefabUtility.SavePrefabAsset 方法保存预制体。

在循环结束后,使用 AssetDatabase.Refresh 对资源进行刷新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System.IO;
using UnityEngine;
using UnityEditor;

public class TraverseAssets
{
public static string path = "Assets/";

[MenuItem("搜索工具/遍历预制体")]
public static void TraversePrefab()
{
var allfiles = Directory.GetFiles(path, "*.prefab", SearchOption.AllDirectories);

foreach (var file in allfiles)
{
GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(file);
if (go)
{
SpriteRenderer sr = go.GetComponent<SpriteRenderer>();
if (sr)
{
sr.sortingOrder = 100;
}
}
PrefabUtility.SavePrefabAsset(go);
}

AssetDatabase.Refresh();
}
}

点击菜单栏按钮,可以看到预制体已经被修改了,Order in Layer 都变成了 100。

至此,我们已经能够遍历资源文件夹,找出预制体,对它们统一进行需求上的处理,并保存修改。

编辑窗口

结合上一篇文章《Unity3D 自定义窗口》,我们可以制作一个窗口,把脚本里的一些参数提取出来,方便编辑。

主要是使用 EditorGUILayout.TextField 把参数呈现到文本输入框,例如 path 和 sortingOrder,在用户修改了文本输入框的内容后,这两个变量参数也会随之修改,在具体逻辑处使用这两个变量参数即可。

注意:因为文本输入框的内容是 string 类型,这里的 sortingOrder 需要使用 int.Parse 进行类型转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System.IO;
using UnityEngine;
using UnityEditor;

public class TraverseAssets : EditorWindow
{
public static string path = "Assets/";
public static string sortingOrder = "100";

[MenuItem("搜索工具/遍历预制体")]
public static void OpenWindow()
{
// 创建窗口对象
TraverseAssets window = GetWindow<TraverseAssets>();

// 设置窗口标题
window.titleContent = new GUIContent("搜索工具");

// 显示窗口
window.Show();
}

void OnGUI()
{
GUILayout.Label("自定义搜索工具,可以遍历资源并修改");

GUILayout.Space(10);

path = EditorGUILayout.TextField("根目录", path);
sortingOrder = EditorGUILayout.TextField("层级排序", sortingOrder);

GUILayout.Space(10);

if (GUILayout.Button("确定", GUILayout.Height(50)))
{
TraversePrefab();
}
}

public static void TraversePrefab()
{
var allfiles = Directory.GetFiles(path, "*.prefab", SearchOption.AllDirectories);

foreach (var file in allfiles)
{
GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(file);
if (go)
{
SpriteRenderer sr = go.GetComponent<SpriteRenderer>();
if (sr)
{
sr.sortingOrder = int.Parse(sortingOrder);
}
}
PrefabUtility.SavePrefabAsset(go);
}

AssetDatabase.Refresh();
}
}

现在点击菜单栏按钮,就会打开一个编辑窗口,可以修改参数,点击确定按钮就会对预制体进行修改并保存。

我们可以修改根目录,指定某个文件夹路径,对部分预制体进行修改,也可以指定层级排序,不需要修改脚本。

小结

使用的方法:

  • 遍历资源文件 Directory.GetFiles
  • 根据路径加载资源 AssetDatabase.LoadAssetAtPath
  • 保存预制体 PrefabUtility.SavePrefabAsset
  • 刷新资源 AssetDatabase.Refresh

可以制作一个编辑窗口,让参数的编辑更加方便。

除了修改层级排序,还可以替换图片、修改材质等,可以自行扩展功能。


Unity3D 遍历预制体
http://weikunou.github.io/2024/08/25/unity-traverse-prefab/
作者
Awake
发布于
2024年8月25日
许可协议