UFL5-4——Editor资源加载模块
Editor资源加载模块
Editor资源加载的主要作用
当项目主要采用AssetBundle资源加载时,用于在开发时进行资源加载,方便资源管理,避免资源重复打包
Editor资源加载的基本原理
利用Unity编辑器拓展中的相关API来进行加载即可
AssetDatabase.LoadAssetAtPath()
EditorGUIUtility.Load()
Editor资源加载的主要作用
避免在开发时频繁的打AB包降低开发效率
方便资源管理,避免资源重复打包
在进行项目开发时,最终发布的项目一般为了达到以下两个目的
减小包体大小
热更新
最终会通过AssetBundle资源加载作为主要加载方式
那么也就是说最终我们发布项目时,几乎所有的的游戏资源都会在AB包中的
AB包最终会放置在 StreamingAssets 中 或者 远程资源服务器 中
但是在开发期间,如果进行频繁的资源打包(资源放入AssetBundle包),会大大降低我们的开发效率。
因此我们在开发功能时,可以不通过AB包加载资源,而是在最终要测试或发布时才把资源整合进AB包。
但是为了方便资源管理,我们也不能将资源放在Resources中来进行加载,因为最终Resources中的资源会被打包出去。
那么此时Editor资源加载的作用就体现出来了,我们可以将资源放进不会被打包的Editor文件夹中,
开发时通过Editor资源加载,测试和发布时使用AssetBundle资源加载。
Editor资源加载的基本原理
利用Unity编辑器拓展相关API:AssetDatabase.LoadAssetAtPath
可以加载工程路径下指定位置资源:EditorGUIUtility.Load
可以加载工程路径下Editor Default Resource文件夹下资源,我们可以根据自己的需求,选择任意API进行使用
具体实现
主要使用的API
AssetDatabase.LoadAssetAtPath(),用于加载单个资源
AssetDatabase.LoadAllAssetRepresentationsAtPath(),用于加载图集资源中的内容(该API用于加载所有子资源)
注意:这两个API加载资源的路径都是从 Assets/...
开始
创建用于放置资源的文件夹
我们可以创建Editor文件夹,以后我们最终会打包为AB包的资源都放置在此处
实现Editor资源管理器
封装API,主要提供加载单个资源以及加载图集资源的API
LoadEditorRes<>
用于加载单个资源
LoadSprite
用于加载某个图集内的图片
LoadSprites
用于加载某个图集,返回键为图片名值为图片的包括所有图集内图片的字典
值得一提的是,由于AssetDatabase
相关API加载资源时,传入的路径参数都要包括后缀名,因此封装的API要根据传入的参数来判断使用什么后缀名
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.Collections;using System.Collections.Generic;using UnityEditor;using UnityEngine;using static TMPro.SpriteAssetUtilities.TexturePacker_JsonArray;public class EditorResManager : BaseManager <EditorResManager >{ private string rootPath = "Assets/Editor/ArtRes/" ; private EditorResManager () { } public T LoadEditorRes <T >(string path ) where T : Object { string suffixName = "" ; if (typeof (T) == typeof (GameObject)) suffixName = ".prefab" ; else if (typeof (T) == typeof (Material)) suffixName = ".mat" ; else if (typeof (T) == typeof (Texture)) suffixName = ".png" ; else if (typeof (T) == typeof (AudioClip)) suffixName = ".mp3" ; T res = AssetDatabase.LoadAssetAtPath<T>(rootPath + path + suffixName); return res; } public Sprite LoadSprite (string path, string spriteName ) { Object[] sprites = AssetDatabase.LoadAllAssetRepresentationsAtPath(rootPath + path + ".png" ); foreach (var item in sprites) { if (spriteName == item.name) return item as Sprite; } return null ; } public Dictionary<string , Sprite> LoadSprites (string path ) { Dictionary<string , Sprite> spriteDic = new Dictionary<string , Sprite>(); Object[] sprites = AssetDatabase.LoadAllAssetRepresentationsAtPath(rootPath + path + ".png" ); foreach (var item in sprites) { spriteDic.Add(item.name, item as Sprite); } return spriteDic; } }
使用示例
1 2 3 4 void Start (){ Instantiate(EditorResManager.Instance.LoadEditorRes<GameObject>("Cube" )); }
输出:
补充:让该脚本主要逻辑仅在编辑器环境下编译
由于该脚本在非Editor文件夹内调用了Editor相关的API,因此,在打包AB包的时候,这里的代码会报错,导致打包不成功
因此我们需要使用预处理器指令,配合UNITY_EDITER
来选择性编译,让该脚本的方法内的实现在非编辑器模式下不会被编译
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 61 62 63 64 65 66 67 68 69 70 71 72 using System.Collections.Generic;using UnityEditor;using UnityEngine;public class EditorResManager : BaseManager <EditorResManager >{ #if UNITY_EDITOR private string rootPath = "Assets/Editor/ArtRes/" ; #endif private EditorResManager () { } public T LoadEditorRes <T >(string path ) where T : Object { #if UNITY_EDITOR string suffixName = "" ; if (typeof (T) == typeof (GameObject)) suffixName = ".prefab" ; else if (typeof (T) == typeof (Material)) suffixName = ".mat" ; else if (typeof (T) == typeof (Texture)) suffixName = ".png" ; else if (typeof (T) == typeof (AudioClip)) suffixName = ".mp3" ; T res = AssetDatabase.LoadAssetAtPath<T>(rootPath + path + suffixName); return res; #else throw new System.Exception("不允许在非编辑器模式下调用该方法加载资源!" ); #endif } public Sprite LoadSprite (string path, string spriteName ) { #if UNITY_EDITOR Object[] sprites = AssetDatabase.LoadAllAssetRepresentationsAtPath(rootPath + path + ".png" ); foreach (var item in sprites) { if (spriteName == item.name) return item as Sprite; } return null ; #else throw new System.Exception("不允许在非编辑器模式下调用该方法加载资源!" ); #endif } public Dictionary<string , Sprite> LoadSprites (string path ) { #if UNITY_EDITOR Dictionary<string , Sprite> spriteDic = new Dictionary<string , Sprite>(); Object[] sprites = AssetDatabase.LoadAllAssetRepresentationsAtPath(rootPath + path + ".png" ); foreach (var item in sprites) { spriteDic.Add(item.name, item as Sprite); } return spriteDic; #else throw new System.Exception("不允许在非编辑器模式下调用该方法加载资源!" ); #endif } }