南阳网站制作价格,网页设计策划案案模板,免费做长图网站,网站正在开发中文章目录 一、Unity资源加载的几种方式1、Inspector窗口拖拽2、Resources3、AssetBundle4、Addressables#xff08;可寻址资源系统#xff09;5、AssetDatabase 二、准备三、同步加载Resources资源1、Resources.Load同步加载单个资源1.1、基本加载1.2、加载指定类型的资源1.… 文章目录 一、Unity资源加载的几种方式1、Inspector窗口拖拽2、Resources3、AssetBundle4、Addressables可寻址资源系统5、AssetDatabase 二、准备三、同步加载Resources资源1、Resources.Load同步加载单个资源1.1、基本加载1.2、加载指定类型的资源1.3、使用泛型加载指定类型的资源 2、Resources.LoadAll同步加载多个资源2.1、基本加载2.2、加载指定类型的资源2.3、使用泛型加载指定类型的资源 四、异步加载Resources文件夹中的资源五、封装一个Resources资源管理器1、封装异步加载资源2、封装同步加载资源3、封装卸载资源方法 六、最终代码完结 一、Unity资源加载的几种方式
1、Inspector窗口拖拽
在脚本中用public声明变量然后在Inspector窗口把要加载的资源拖拽给该脚本的变量。不建议在大型项目使用。在公司的项目也不要用。如果你是独立游戏开发者则可以用。不支持热更新。
2、Resources
用Resources.Load方法、Resources.LoadAsync方法、Resources.LoadAll方法来加载资源。可以在商业项目使用包括公司的项目。但是Resources文件夹中可以存放的资源有限大概只能存储2G左右的资源因此要谨慎使用。不支持热更新。
3、AssetBundle
用AssetBundle.LoadFromXXX方法来加载资源。商业项目常用的资源加载方案如果你在公司做项目则推荐用这种方式来加载资源。效率比Resources加载高占用内存小正式发布游戏后资源所占用的空间也小。支持热更新。
4、Addressables可寻址资源系统
可以理解为高级的AssetBundle资源管理由Unity内部自动完成。但是目前还在发展中可能有bug。主流的商业游戏都是使用AssetBundle来做资源加载的。支持热更新。
5、AssetDatabase
用AssetDatabase.LoadAssetAtPath方法来加载资源。仅限于编辑器模式主要用于在编辑器模式下用代码更改本地文件。游戏运行时不会用这种方案加载资源。不支持热更新。
二、准备
使用前必须在项目中创建一个名叫Resources的文件夹这个名字是固定的。
三、同步加载Resources资源
1、Resources.Load同步加载单个资源
1.1、基本加载 Resources.Load(string 要加载的资源的路径) 返回值是Object型。
如果有多个相同路径的资源则只会返回找到的第一个资源。
调用案例
GameObject go Resources.Load(Prefabs/Cube) as GameObject;1.2、加载指定类型的资源 Resources.Load(string 要加载的资源的路径, System.Type 要加载的资源的类型的Type对象) 返回值是Object型。
如果有多个相同类型且相同路径的资源则只会返回找到的第一个资源。
调用案例
GameObject go Resources.Load(Prefabs/Cube, typeof(GameObject)) as GameObject;1.3、使用泛型加载指定类型的资源 Resources.Load要加载的资源的类型(string 要加载的资源的路径) 返回值是T型。
返回值是要加载的资源的类型。如果有多个相同类型且相同路径的资源则只会返回找到的第一个资源。
调用案例
GameObject go Resources.LoadGameObject(Prefabs/Cube);2、Resources.LoadAll同步加载多个资源
2.1、基本加载 Resources.LoadAll(string 要加载的资源的文件夹路径或文件路径) 返回值是Object[]型。
同步加载Resources文件夹中指定路径的文件夹中的所有资源包括其中子孙文件夹中的所有资源然后返回到一个Object[]型数组。
如果该路径是一个文件则只会加载该文件并返回到一个Object[]型数组。如果没有加载到任何资源则返回一个没有任何元素的Object[]型数组。
调用案例
Object[] gos Resources.LoadAll(Prefabs);
for (int i 0; i gos.Length; i)
{Instantiate(gos[i] as GameObject);
}2.2、加载指定类型的资源 Resources.LoadAll(string 要加载的资源的文件夹路径或文件路径,System.Type 要加载的资源的类型的Type对象) 返回值是Object[]型。
同步加载Resources文件夹中指定路径的文件夹中的指定类型的所有资源包括其中子孙文件夹中的该类型的所有资源然后返回到一个Object[]型数组。
如果该路径是一个该指定类型的文件则只会加载该文件并返回到一个Object[]型数组。如果没有加载到任何资源则返回一个没有任何元素的Object[]型数组。
调用案例
Object[] gos Resources.LoadAll(Prefabs, typeof(GameObject));
for (int i 0; i gos.Length; i)
{Instantiate(gos[i] as GameObject);
}2.3、使用泛型加载指定类型的资源 Resources.LoadAll泛型T类型(string 要加载的资源的文件夹路径或文件路径) 返回值是T[]型。
同步加载Resources文件夹中指定路径的文件夹中的指定类型的所有资源包括其中子孙文件夹中的该类型的所有资源然后返回到一个T[]型数组。
如果该路径是一个该指定类型的文件则只会加载该文件并返回到一个T[]型数组。如果没有加载到任何资源则返回一个没有任何元素的T[]型数组。
调用案例
GameObject[] gos Resources.LoadAllGameObject(Prefabs);
for (int i 0; i gos.Length; i)
{Instantiate(gos[i]);
}四、异步加载Resources文件夹中的资源
Resources.LoadAsync异步加载单个资源方法
使用泛型加载指定类型的资源 Resources.LoadAsync泛型T类型(string 要加载的资源的路径) 返回值是ResourceRequest类型。
一般配合协程来使用。在协程中可以使用yield return来等待资源加载。
如果有多个相同路径的资源则只会加载找到的第一个资源。
调用案例
void Start()
{StartCoroutine(LoadAsyncCoroutine());
}IEnumerator LoadAsyncCoroutine(){//开始异步加载资源ResourceRequest rr Resources.LoadAsyncGameObject(Prefabs/Cube);//等待资源加载完毕yield return rr;//加载完成执行逻辑Instantiate(rr.asset);
}五、封装一个Resources资源管理器
1、封装异步加载资源
注意这个脚本依赖Mono管理器【unity进阶知识2】Mono管理器
public class ResourcesManager : SingletonResourcesManager
{/// summary/// 异步加载Resources文件夹中指定类型的资源/// /summarypublic void LoadAsyncT(string path, UnityActionT callback null) where T : Object{MonoManager.Instance.StartCoroutine(LoadAsyncCoroutine(path, callback));}IEnumerator LoadAsyncCoroutineT(string path, UnityActionT callback null) where T : Object{ResourceRequest resourceRequest Resources.LoadAsyncT(path);yield return resourceRequest;callback?.Invoke(resourceRequest.asset as T);}
}调用效果和前面一样
ResourcesManager.Instance.LoadAsyncGameObject(Prefabs/Cube, Callback);void Callback(GameObject obj){Instantiate(obj);
}或者
ResourcesManager.Instance.LoadAsyncGameObject(Prefabs/Cube, (obj){Instantiate(obj);
});2、封装同步加载资源
同步加载封装虽然是一样的但是好处是自己封装可以统一管理和进行自定义注释
/// summary
/// para同步加载Resources文件夹中指定类型的资源。/para
/// para如果有多个相同类型且相同路径的资源则只会返回找到的第一个资源。/para
/// /summary
/// typeparam nameT要加载的资源的类型/typeparam
/// param namepath要加载的资源的路径。例如Prefabs/Cube表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。/param
public T LoadT(string path) where T : Object
{return Resources.LoadT(path);
}调用
GameObject[] gos ResourcesManager.Instance.LoadAllGameObject(Prefabs);
for (int i 0; i gos.Length; i)
{Instantiate(gos[i]);
}3、封装卸载资源方法
通过Resources加载的资源就算销毁了但是它还是占在内存里面没有释放所以我们需要卸载资源比如切换场景的时候
/// summary
/// para异步卸载所有用Resources方式加载到内存中且当前没有被任何地方使用的资源。/para
/// para例如要卸载某一个用Resources方式加载的预制体则必须确保场景中所有这个预制体创建的物体都被销毁了且这个预制体资源没有赋值给任何脚本中的任何变量。/para
/// para如果有可以把该变量也赋值为null这样本方法才能成功释放它。/para
/// /summary
/// param namecallback资源卸载完毕后执行的逻辑/param
public void UnloadUnusedAssets(UnityAction callback null)
{MonoManager.Instance.StartCoroutine(UnLoadUnusedAssetsCoroutine(callback));
}
IEnumerator UnLoadUnusedAssetsCoroutine(UnityAction callback null)
{//异步操作对象记录了异步操作的数据。AsyncOperation asyncOperation Resources.UnloadUnusedAssets();//等待资源卸载while (asyncOperation.progress 1)yield return null;//资源卸载完毕后执行的逻辑callback?.Invoke();
}调用
ResourcesManager.Instance.UnloadUnusedAssets(()
{Debug.Log(异步卸载所有资源成功);
});六、最终代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using XYFrame;/// summary
/// Resources资源加载管理器
/// 这个脚本依赖Mono管理器。
/// 要加载的资源必须放到项目中名叫Resources的文件夹中。项目中可以有多个名叫Resources的文件夹但如此一来必须避免资源的路径相同。
/// /summary
public class ResourcesManager : SingletonResourcesManager
{#region 同步加载单个资源/// summary/// para同步加载Resources文件夹中的资源。/para/// para如果有多个相同路径的资源则只会返回找到的第一个资源。/para/// /summary/// param namepath要加载的资源的路径。例如Prefabs/Cube表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。/parampublic Object Load(string path){return Resources.Load(path);}/// summary/// para同步加载Resources文件夹中指定类型的资源。/para/// para如果有多个相同类型且相同路径的资源则只会返回找到的第一个资源。/para/// /summary/// param namepath要加载的资源的路径。例如Prefabs/Cube表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。/param/// param namesystemTypeInstance要加载的资源的类型的Type对象。例如typeof(GameObject)表示要加载的资源的类型是GameObject型。/param/// returns/returnspublic Object Load(string path, System.Type systemTypeInstance){return Resources.Load(path, systemTypeInstance);}/// summary/// para同步加载Resources文件夹中指定类型的资源。/para/// para如果有多个相同类型且相同路径的资源则只会返回找到的第一个资源。/para/// /summary/// typeparam nameT要加载的资源的类型/typeparam/// param namepath要加载的资源的路径。例如Prefabs/Cube表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。/parampublic T LoadT(string path) where T : Object{return Resources.LoadT(path);}#endregion#region 同步加载多个资源/// summary/// para同步加载Resources文件夹中指定路径的文件夹中的所有资源包括其中子孙文件夹中的所有资源然后返回到一个Object[]型数组。/para/// para如果该路径是一个文件则只会加载该文件并返回到一个Object[]型数组。/para/// para如果没有加载到任何资源则返回一个没有任何元素的Object[]型数组。/para/// /summary/// param namepath要加载的文件夹或文件的路径。例如Prefabs表示Resources文件夹中的Prefabs文件夹。例如Prefabs/Cube表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。/parampublic Object[] LoadAll(string path){return Resources.LoadAll(path);}/// summary/// para同步加载Resources文件夹中指定路径的文件夹中指定类型的所有资源包括其中子孙文件夹中的该类型的所有资源然后返回到一个Object[]型数组。/para/// para如果该路径是一个该指定类型的文件则只会加载该文件并返回到一个Object[]型数组。/para/// para如果没有加载到任何资源则返回一个没有任何元素的Object[]型数组。/para/// /summary/// param namepath要加载的文件夹或文件的路径。例如Prefabs表示Resources文件夹中的Prefabs文件夹。例如Prefabs/Cube表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。/param/// param namesystemTypeInstance要加载的资源的类型的Type对象。例如typeof(GameObject)表示要加载的资源的类型是GameObject型。/parampublic Object[] LoadAll(string path, System.Type systemTypeInstance){return Resources.LoadAll(path, systemTypeInstance);}/// summary/// para同步加载Resources文件夹中指定路径的文件夹中指定类型的所有资源包括其中子孙文件夹中的该类型的所有资源然后返回到一个Object[]型数组。/para/// para如果该路径是一个该指定类型的文件则只会加载该文件并返回到一个Object[]型数组。/para/// para如果没有加载到任何资源则返回一个没有任何元素的Object[]型数组。/para/// /summary/// typeparam nameT要加载的资源的类型/typeparam/// param namepath要加载的文件夹或文件的路径。例如Prefabs表示Resources文件夹中的Prefabs文件夹。例如Prefabs/Cube表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。/parampublic T[] LoadAllT(string path) where T : Object{return Resources.LoadAllT(path);}/// summary/// para同步把Resources文件夹中指定路径的文件夹及其所有子孙文件夹中所有指定类型的资源添加到一个新建的字典中并返回该字典。/para/// para应保证Prefabs文件夹中以及它的子孙文件夹中没有重名的资源如果有重名的则只会添加找到的第一个资源进字典其它重名的资源不会进到字典中。/para/// /summary/// typeparam nameT要加载的资源类型/typeparam/// param namepath资源的路径。例如Folder/Res表示Resources文件夹中的Folder文件夹中的Res文件夹/parampublic Dictionarystring, T LoadAllIntoDictionaryT(string path) where T : Object{Dictionarystring, T dic new Dictionarystring, T();T[] temp Resources.LoadAllT(path);for (int i 0; i temp.Length; i){if (!dic.ContainsKey(temp[i].name))//字典不存在该键才添加进去。这样可以防止字典的键名重复而报错。{dic.Add(temp[i].name, temp[i]);}else//如果字典已经存在该键则跳过这个资源并输出警告不将它加入到字典中{Debug.LogWarning(string.Format(Resources/{0}的子孙文件夹的资源{1}与已经添加到字典中的资源重名因此无法将它添加到字典中请确保加载的资源的名字是唯一的。, path, temp[i].name));}}return dic;}/// summary/// para同步把Resources文件夹中指定路径及其所有子孙文件夹中所有指定类型的资源添加到指定的字典中/para/// /summary/// typeparam nameT要加载的资源类型/typeparam/// param namepath资源的路径。例如Folder/Res表示Resources文件夹中的Folder文件夹中的Res文件夹/param/// param namedictionary指定的字典/parampublic void LoadAllIntoDictionaryT(string path, Dictionarystring, T dictionary) where T : Object{T[] temp Resources.LoadAllT(path);for (int i 0; i temp.Length; i){if (!dictionary.ContainsKey(temp[i].name))//字典不存在该键才添加进去。这样可以防止字典的键名重复而报错。{dictionary.Add(temp[i].name, temp[i]);}else//如果字典已经存在该键则跳过这个资源并输出警告不将它加入到字典中{Debug.LogWarning(string.Format(Resources/{0}的子孙文件夹的资源{1}与已经添加到字典中的资源重名因此无法将它添加到字典中请确保加载的资源的名字是唯一的并且传入参数的字典中不包含该名字的资源。, path, temp[i].name));}}}#endregion#region 异步加载单个资源/// summary/// para异步加载Resources文件夹中的资源。/para/// para如果有多个相同路径的资源则只会加载找到的第一个资源。/para/// /summary/// param namepath要加载的资源的路径。例如Prefabs/Cube表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。/param/// param namecallback资源加载完毕后要执行的逻辑。参数表示加载的资源。/parampublic void LoadAsync(string path, UnityActionObject callback null){MonoManager.Instance.StartCoroutine(LoadAsyncCoroutine(path, callback));}IEnumerator LoadAsyncCoroutine(string path, UnityActionObject callback null){ResourceRequest resourceRequest Resources.LoadAsync(path);yield return resourceRequest;callback?.Invoke(resourceRequest.asset);}/// summary/// para异步加载Resources文件夹中指定类型的资源。/para/// para如果有多个相同类型且相同路径的资源则只会加载找到的第一个资源。/para/// /summary/// param namepath/param/// param nametype要加载的资源的类型的Type对象。例如typeof(GameObject)表示要加载的资源的类型是GameObject型。/param/// param namecallback资源加载完毕后要执行的逻辑。参数表示加载的资源。/parampublic void LoadAsync(string path, System.Type type, UnityActionObject callback null){MonoManager.Instance.StartCoroutine(LoadAsyncCoroutine(path, type, callback));}IEnumerator LoadAsyncCoroutine(string path, System.Type type, UnityActionObject callback null){ResourceRequest resourceRequest Resources.LoadAsync(path, type);yield return resourceRequest;callback?.Invoke(resourceRequest.asset);}/// summary/// para异步加载Resources文件夹中指定类型的资源。/para/// para如果有多个相同类型且相同路径的资源则只会加载找到的第一个资源。/para/// /summary/// typeparam nameT加载的资源的类型/typeparam/// param namepath要加载的资源的路径。例如Prefabs/Cube表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。/param/// param namecallback资源加载完毕后要执行的逻辑/parampublic void LoadAsyncT(string path, UnityActionT callback null) where T : Object{MonoManager.Instance.StartCoroutine(LoadAsyncCoroutine(path, callback));}IEnumerator LoadAsyncCoroutineT(string path, UnityActionT callback null) where T : Object{ResourceRequest resourceRequest Resources.LoadAsyncT(path);yield return resourceRequest;callback?.Invoke(resourceRequest.asset as T);}#endregion#region 卸载资源/// summary/// para异步卸载所有用Resources方式加载到内存中且当前没有被任何地方使用的资源。/para/// para例如要卸载某一个用Resources方式加载的预制体则必须确保场景中所有这个预制体创建的物体都被销毁了且这个预制体资源没有赋值给任何脚本中的任何变量。/para/// para如果有可以把该变量也赋值为null这样本方法才能成功释放它。/para/// /summary/// param namecallback资源卸载完毕后执行的逻辑/parampublic void UnloadUnusedAssets(UnityAction callback null){MonoManager.Instance.StartCoroutine(UnLoadUnusedAssetsCoroutine(callback));}IEnumerator UnLoadUnusedAssetsCoroutine(UnityAction callback null){//异步操作对象记录了异步操作的数据。AsyncOperation asyncOperation Resources.UnloadUnusedAssets();//等待资源卸载while (asyncOperation.progress 1)yield return CoroutineTool.WaitForFrame();//资源卸载完毕后执行的逻辑callback?.Invoke();}/// summary/// para同步卸载指定的资源。/para/// para只能卸载非GameObject类型和Component类型例如Mesh、Texture、Material、Shader。如果卸载了不让卸载的资源则会报错。/para/// para如果随后加载的任何场景或资源引用了该资源将导致从磁盘中加载该资源的新实例。此新实例将与先前卸载的对象相互独立。/para/// /summary/// param nameassetToUnload要卸载的资源/parampublic void UnloadAsset(Object assetToUnload){Resources.UnloadAsset(assetToUnload);}#endregion
}完结
赠人玫瑰手有余香如果文章内容对你有所帮助请不要吝啬你的点赞评论和关注你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法也欢迎评论私信告诉我哦
好了我是向宇https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者闲暇之余边学习边记录分享站在巨人的肩膀上通过学习前辈们的经验总是会给我很多帮助和启发如果你遇到任何问题也欢迎你评论私信或者加群找我 虽然有些问题我也不一定会但是我会查阅各方资料争取给出最好的建议希望可以帮助更多想学编程的人共勉~