当前位置: 首页 > article >正文

Unity3D 遍历预制体

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

遍历预制体

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

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

遍历文件路径

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

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

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

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 对资源进行刷新。

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 进行类型转换。

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

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

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


http://www.kler.cn/news/282967.html

相关文章:

  • Zookeeper集成Clickhouse方法以及作用
  • 大模型之二十八-语音识别Whisper进阶
  • Spring Boot与桥接模式:构建灵活的产品分类体系
  • 生信圆桌:专业生信服务器与平台服务的提供者
  • How do I do function calling in Azure Openai using the javascript sdk
  • 系统设计——登录流程
  • Spring Boot启用GZIP压缩
  • 【Kafka】Windows下安装Kafka(全面)
  • wpf datagrid通过点击单元格 获取行列索引2.0
  • golang RSA 解密前端jsencrypt发送的数据时异常 crypto/rsa: decryption error 解决方法
  • P1149 [NOIP2008 提高组] 火柴棒等式
  • OpenHarmony 实战开发——ArkUI中的线程和看门狗机制
  • Linux tty模式下无法使用回滚功能解决(shift+pgup方法不管用)
  • STL中queue、stack的实现与容器适配器的讲解
  • C++入门篇1
  • 【前端面试】React深度学习(下)
  • 【软件测试】自动化测试如此盛行,手工测试该何去何从?
  • Shell脚本入门:多命令处理
  • wpf prism 《3》 弹窗 IOC
  • RabbitMQ练习(Publish/Subscribe)
  • GPT-SoVITS-WebUI 初体验
  • C++练习题:进阶算法——动态规划
  • 面试题集锦:数据库
  • 米壳AI:做塞尔维亚跨境电商,用这个工具翻译产品主图,语言不再是难题!
  • KEYSIGHT是德 Infiniium EXR系列 示波器
  • LavaDome:一款基于ShadowDOM的DOM树安全隔离与封装工具
  • 大语言模型中,role为user、assistant、system有什么区别
  • 我主编的电子技术实验手册(18)——认识电感
  • 【数学建模】国赛论文写作教学——问题重述与分析
  • HTML实现俄罗斯方块