【unity游戏开发——编辑器扩展】AssetDatabase公共类在编辑器环境中管理和操作项目中的资源

注意:考虑到编辑器扩展的内容比较多,我将编辑器扩展的内容分开,并全部整合放在【unity游戏开发------编辑器扩展】专栏里,感兴趣的小伙伴可以前往逐一查看学习。

文章目录

前言

AssetDatabase公共类是 Unity 引擎中的一个编辑器类,用于在编辑器环境中管理和操作项目中的资源(Assets)。它提供了一系列静态方法,使得开发者能够在编辑器脚本中进行资源的创建、拷贝、移动、删除等操作。

官方文档:AssetDatabase

一、AssetDatabase常用API

1、创建资源

1.1 API

我们可以通过代码动态创建一些资源

csharp 复制代码
AssetDatabase.CreateAsset(资源,路径);

注意

  • 路径从 Assets/...开始
  • 不能在StreamingAssets中创建资源,
  • 不能创建预设体
  • 只能创建资源相关,例如材质球等
  • 路径需要写后缀

1.2 示例

csharp 复制代码
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
    	// 创建资源按钮
        if (GUILayout.Button("创建资源"))
        {
            // 创建一个材质,使用URP的Lit着色器
            Material mat = new Material(Shader.Find("Universal Render Pipeline/Lit"));
            // 将材质保存为Assets/Resources/TestURPLitMaterial.mat
            AssetDatabase.CreateAsset(mat, "Assets/Resources/TestURPLitMaterial.mat");
        }
    }
}

效果

2、创建文件夹

2.1 API

csharp 复制代码
AssetDatabase.CreateFolder(父文件夹路径,新文件夹名)

注意

  • 父文件夹路径从 Assets/...开始

2.2 示例

csharp 复制代码
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
    	// 创建文件夹按钮
        if (GUILayout.Button("创建文件夹"))
        {
            // 在Assets/Resources下创建一个名为MyTestFolder的文件夹
            AssetDatabase.CreateFolder("Assets/Resources", "MyTestFolder");
        }
    }
}

效果

3、拷贝资源

3.1 API

csharp 复制代码
AssetDatabase.CopyAsset(源资源路径,目标路径)

注意

  • 需要写后缀名
  • 路径从 Assets/...开始

3.2 示例

csharp 复制代码
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
    	// 拷贝资源按钮
        if (GUILayout.Button("拷贝资源"))
        {
            // 将Assets/Resources/TestURPLitMaterial.mat拷贝到Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat
            AssetDatabase.CopyAsset("Assets/Resources/TestURPLitMaterial.mat", "Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat");
        }
    }
}

效果

4、移动资源

4.1 API

csharp 复制代码
AssetDatabase.MoveAsset(老路径, 新路径);

注意

  • 路径从 Assets/...开始

4.2 示例

csharp 复制代码
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
    	// 移动资源按钮
        if (GUILayout.Button("移动资源"))
        {
            // 将Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat移动到Assets/Resources/TestURPLitMaterialCopy.mat
            AssetDatabase.MoveAsset("Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat","Assets/Resources/TestURPLitMaterialCopy.mat");
        }
    }
}

5、删除资源

5.1 API

csharp 复制代码
AssetDatabase.DeleteAsset(资源路径)

注意

  • 路径从 Assets/...开始

5.2 示例

csharp 复制代码
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
    	// 删除资源按钮
        if (GUILayout.Button("删除资源"))
        {
            // Assets/Resources/TestURPLitMaterialCopy.mat
            AssetDatabase.DeleteAsset("Assets/Resources/TestURPLitMaterialCopy.mat");
        }
    }
}

效果

6、批量删除资源

6.1 API

csharp 复制代码
AssetDatabase.DeleteAssets(string[] 路径们, List<string> 用于存储删除失败的路径)

注意

  • 路径从 Assets/...开始

6.2 示例

csharp 复制代码
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
    	// 批量删除资源按钮
        if (GUILayout.Button("批量删除资源"))
        {
            // 创建一个列表,用于存储删除失败的资源
            List<string> failList = new List<string>();
            // 批量删除Assets/Resources/TestURPLitMaterial.mat和Assets/Resources/TestURPLitMaterial2.mat
            AssetDatabase.DeleteAssets(
                new string[] { "Assets/Resources/TestURPLitMaterial.mat", "Assets/Resources/TestURPLitMaterial2.mat" }, failList);
                
            // 遍历删除失败的资源列表,并输出到控制台
            for (int i = 0; i < failList.Count; i++)
            {
                Debug.Log(failList[i]);
            }
        }
    }
}

效果

7、获取资源路径

7.1 API

csharp 复制代码
AssetDatabase.GetAssetPath(资源)

注意

  • 可以配合Selection选中资源一起使用

7.2 示例

csharp 复制代码
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
    	// 获取资源路径按钮
        if (GUILayout.Button("获取资源路径"))
        {
            // 输出当前选中的资源的路径
            Debug.Log(AssetDatabase.GetAssetPath(Selection.activeObject));
        }
    }
}

效果

8、根据路径加载资源

8.1 API

csharp 复制代码
AssetDatabase.LoadAssetAtPath(资源路径) 

注意

  • 路径从Assets/...开始

8.2 示例

csharp 复制代码
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
    	// 加载资源按钮
        if (GUILayout.Button("加载资源"))
        {
            // 加载Assets/测试文件.txt,并输出其名称
            TextAsset txt = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/测试文件.txt");
            Debug.Log(txt.name);
        }
    }
}

效果

9、刷新项目资源

9.1 API

AssetDatabase.Refresh()是Unity编辑器API中的一个重要方法,用于刷新项目资源数据库。当你在Unity项目文件夹中添加、删除或修改资源文件时,这个方法可以确保Unity编辑器能够识别这些更改。

csharp 复制代码
AssetDatabase.Refresh()

Unity通常会自动在适当时候调用刷新,但有时需要手动触发。比如当你通过代码创建或修改了资源文件,需要执行刷新,我们才能在Project窗口中显示最新的内容,否则每次都需要手动调用ctrl+R刷新,这个API其实就是帮我们省略手动刷新这一步。

9.2 示例

csharp 复制代码
using System.IO;
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
    	// 创建文件并刷新资源按钮
        if (GUILayout.Button("创建文件并刷新资源"))
        {
            // 创建文件时,如果不使用Unity相关API的话,需要调用刷新,才能在Project窗口中显示
            File.WriteAllText(Application.dataPath + "/Resources/test2.txt", "内容内容内容");
            AssetDatabase.Refresh();
        }
    }
}

效果

10、返回资源所属的AB包名

10.1 API

csharp 复制代码
string bundleName = AssetDatabase.GetImplicitAssetBundleName(资源路径);

注意

  • 路径从Assets/...开始
  • 返回该资源隐式关联的AssetBundle名称(如果有的话)
  • 如果资源没有被分配到任何AssetBundle,返回空字符串("")

10.2 示例

csharp 复制代码
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
    	// 返回资源所属的AB包名按钮
        if (GUILayout.Button("返回资源所属的AB包名"))
        {
            string assetPath = "Assets/Resources/MyPrefab.prefab";
	        string bundleName = AssetDatabase.GetImplicitAssetBundleName(assetPath);
	        
	        if (!string.IsNullOrEmpty(bundleName))
	        {
	            Debug.Log($"资源 {assetPath} 属于AssetBundle: {bundleName}");
	        }
	        else
	        {
	            Debug.Log($"资源 {assetPath} 不属于任何AssetBundle");
	        }
        }
    }
}

效果

二、最终代码

csharp 复制代码
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class TestAssetDatabaseEditorWindow : EditorWindow
{
    [MenuItem("编辑器拓展/自定义窗口拓展/AssetDatabase窗口拓展")]
    private static void OpenWindow()
    {
        TestAssetDatabaseEditorWindow win = EditorWindow.GetWindow<TestAssetDatabaseEditorWindow>();
        win.Show();
    }

    private void OnGUI()
    {
        // 创建资源按钮
        if (GUILayout.Button("创建资源"))
        {
            // 创建一个材质,使用URP的Lit着色器
            Material mat = new Material(Shader.Find("Universal Render Pipeline/Lit"));
            // 将材质保存为Assets/Resources/TestURPLitMaterial.mat
            AssetDatabase.CreateAsset(mat, "Assets/Resources/TestURPLitMaterial.mat");
        }

        // 创建文件夹按钮
        if (GUILayout.Button("创建文件夹"))
        {
            // 在Assets/Resources下创建一个名为MyTestFolder的文件夹
            AssetDatabase.CreateFolder("Assets/Resources", "MyTestFolder");
        }

        // 拷贝资源按钮
        if (GUILayout.Button("拷贝资源"))
        {
            // 将Assets/Resources/TestURPLitMaterial.mat拷贝到Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat
            AssetDatabase.CopyAsset("Assets/Resources/TestURPLitMaterial.mat", "Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat");
        }

        // 移动资源按钮
        if (GUILayout.Button("移动资源"))
        {
            // 将Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat移动到Assets/Resources/TestURPLitMaterialCopy.mat
            AssetDatabase.MoveAsset("Assets/Resources/MyTestFolder/TestURPLitMaterialCopy.mat","Assets/Resources/TestURPLitMaterialCopy.mat");
        }

        // 删除资源按钮
        if (GUILayout.Button("删除资源"))
        {
            // Assets/Resources/TestURPLitMaterialCopy.mat
            AssetDatabase.DeleteAsset("Assets/Resources/TestURPLitMaterialCopy.mat");
        }

        // 批量删除资源按钮
        if (GUILayout.Button("批量删除资源"))
        {
            // 创建一个列表,用于存储删除失败的资源
            List<string> failList = new List<string>();
            // 批量删除Assets/Resources/TestURPLitMaterial.mat和Assets/Resources/TestURPLitMaterial2.mat
            AssetDatabase.DeleteAssets(
                new string[] { "Assets/Resources/TestURPLitMaterial.mat", "Assets/Resources/TestURPLitMaterial2.mat" }, failList);

            // 遍历删除失败的资源列表,并输出到控制台
            for (int i = 0; i < failList.Count; i++)
            {
                Debug.Log(failList[i]);
            } 
        }

        // 获取资源路径按钮
        if (GUILayout.Button("获取资源路径"))
        {
            // 输出当前选中的资源的路径
            Debug.Log(AssetDatabase.GetAssetPath(Selection.activeObject));
        }

        // 加载资源按钮
        if (GUILayout.Button("加载资源"))
        {
            // 加载Assets/测试文件.txt,并输出其名称
            TextAsset txt = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/测试文件.txt");
            Debug.Log(txt.name);
        }
        
        // 创建文件并刷新资源按钮
        if (GUILayout.Button("创建文件并刷新资源"))
        {
            // 创建文件时,如果不使用Unity相关API的话,需要调用刷新,才能在Project窗口中显示
            File.WriteAllText(Application.dataPath + "/Resources/test2.txt", "内容内容内容");
            AssetDatabase.Refresh();
        }

        // 返回资源所属的AB包名按钮
        if (GUILayout.Button("返回资源所属的AB包名"))
        {
            string assetPath = "Assets/Resources/MyPrefab.prefab";
	        string bundleName = AssetDatabase.GetImplicitAssetBundleName(assetPath);
	        
	        if (!string.IsNullOrEmpty(bundleName))
	        {
	            Debug.Log($"资源 {assetPath} 属于AssetBundle: {bundleName}");
	        }
	        else
	        {
	            Debug.Log($"资源 {assetPath} 不属于任何AssetBundle");
	        }
        }
    }
}

专栏推荐

地址
【unity游戏开发入门到精通------C#篇】
【unity游戏开发入门到精通------unity通用篇】
【unity游戏开发入门到精通------unity3D篇】
【unity游戏开发入门到精通------unity2D篇】
【unity实战】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架/工具集开发】
【unity游戏开发------模型篇】
【unity游戏开发------InputSystem】
【unity游戏开发------Animator动画】
【unity游戏开发------UGUI】
【unity游戏开发------联网篇】
【unity游戏开发------优化篇】
【unity游戏开发------shader篇】
【unity游戏开发------编辑器扩展】

完结

好了,我是向宇,博客地址:https://xiangyu.blog.csdn.net,如果学习过程中遇到任何问题,也欢迎你评论私信找我。

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

相关推荐
行走的陀螺仪2 小时前
.vscode 文件夹配置详解
前端·ide·vscode·编辑器·开发实践
我一身正气怎能输6 小时前
游戏大厂A*寻路优化秘籍:流畅不卡顿
人工智能·游戏
avi911111 小时前
发现一个宝藏Unity开源AVG框架,视觉小说的脚手架
unity·开源·框架·插件·tolua·avg
点金石游戏出海13 小时前
玩家为何退出、不付费?读懂这些关键的“行为数据”,解锁增长密码!
游戏·数据分析·用户分析·游戏运营
艾莉丝努力练剑16 小时前
【Python基础:语法第一课】Python 基础语法详解:变量、类型、动态特性与运算符实战,构建完整的编程基础认知体系
大数据·人工智能·爬虫·python·pycharm·编辑器
我一身正气怎能输16 小时前
游戏导航网格地图如何自动切割成多边形区域——技术详解大白话长文
游戏
skywalk816317 小时前
FreeBSD系统安装VSCode Server(未成功,后来是在FreeBSD系统里的Linux虚拟子系统里安装启动了Code Server)
ide·vscode·编辑器·freebsd
深海潜水员17 小时前
【MonoGame游戏开发】| 牧场物语实现 第一卷 : 农场基础实现 (下)
vscode·游戏·c#·.net·monogame
一线灵1 天前
跨平台游戏引擎 Axmol-2.10.0 发布
游戏引擎
有一个好名字1 天前
LeetCode跳跃游戏:思路与题解全解析
算法·leetcode·游戏