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

沈阳网站制作思路网络河南省工程信息网官网

沈阳网站制作思路网络,河南省工程信息网官网,搜索引擎优化课程,菏泽住房和城乡建设局网站文章目录 一、Unity资源加载的几种方式1、Inspector窗口拖拽2、Resources3、AssetBundle4、Addressables(可寻址资源系统)5、AssetDatabase 二、准备三、同步加载Resources资源1、Resources.Load同步加载单个资源1.1、基本加载1.2、加载指定类型的资源1.…

文章目录

  • 一、Unity资源加载的几种方式
    • 1、Inspector窗口拖拽
    • 2、Resources
    • 3、AssetBundle
    • 4、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.Load<GameObject>("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.LoadAll<GameObject>("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.LoadAsync<GameObject>("Prefabs/Cube");//等待资源加载完毕yield return rr;//加载完成执行逻辑Instantiate(rr.asset);
}

五、封装一个Resources资源管理器

1、封装异步加载资源

注意这个脚本依赖Mono管理器:【unity进阶知识2】Mono管理器

public class ResourcesManager : Singleton<ResourcesManager>
{/// <summary>/// 异步加载Resources文件夹中指定类型的资源/// </summary>public void LoadAsync<T>(string path, UnityAction<T> callback = null) where T : Object{MonoManager.Instance.StartCoroutine(LoadAsyncCoroutine(path, callback));}IEnumerator LoadAsyncCoroutine<T>(string path, UnityAction<T> callback = null) where T : Object{ResourceRequest resourceRequest = Resources.LoadAsync<T>(path);yield return resourceRequest;callback?.Invoke(resourceRequest.asset as T);}
}

调用,效果和前面一样

ResourcesManager.Instance.LoadAsync<GameObject>("Prefabs/Cube", Callback);void Callback(GameObject obj){Instantiate(obj);
}

或者

ResourcesManager.Instance.LoadAsync<GameObject>("Prefabs/Cube", (obj)=>{Instantiate(obj);
});

2、封装同步加载资源

同步加载封装虽然是一样的,但是好处是自己封装可以统一管理和进行自定义注释

/// <summary>
/// <para>同步加载Resources文件夹中指定类型的资源。</para>
/// <para>如果有多个相同类型,且相同路径的资源,则只会返回找到的第一个资源。</para>
/// </summary>
/// <typeparam name="T">要加载的资源的类型</typeparam>
/// <param name="path">要加载的资源的路径。例如"Prefabs/Cube"表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。</param>
public T Load<T>(string path) where T : Object
{return Resources.Load<T>(path);
}

调用

GameObject[] gos = ResourcesManager.Instance.LoadAll<GameObject>("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 name="callback">资源卸载完毕后执行的逻辑</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 : Singleton<ResourcesManager>
{#region 同步加载单个资源/// <summary>/// <para>同步加载Resources文件夹中的资源。</para>/// <para>如果有多个相同路径的资源,则只会返回找到的第一个资源。</para>/// </summary>/// <param name="path">要加载的资源的路径。例如"Prefabs/Cube"表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。</param>public Object Load(string path){return Resources.Load(path);}/// <summary>/// <para>同步加载Resources文件夹中指定类型的资源。</para>/// <para>如果有多个相同类型,且相同路径的资源,则只会返回找到的第一个资源。</para>/// </summary>/// <param name="path">要加载的资源的路径。例如"Prefabs/Cube"表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。</param>/// <param name="systemTypeInstance">要加载的资源的类型的Type对象。例如typeof(GameObject)表示要加载的资源的类型是GameObject型。</param>/// <returns></returns>public Object Load(string path, System.Type systemTypeInstance){return Resources.Load(path, systemTypeInstance);}/// <summary>/// <para>同步加载Resources文件夹中指定类型的资源。</para>/// <para>如果有多个相同类型,且相同路径的资源,则只会返回找到的第一个资源。</para>/// </summary>/// <typeparam name="T">要加载的资源的类型</typeparam>/// <param name="path">要加载的资源的路径。例如"Prefabs/Cube"表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。</param>public T Load<T>(string path) where T : Object{return Resources.Load<T>(path);}#endregion#region 同步加载多个资源/// <summary>/// <para>同步加载Resources文件夹中指定路径的文件夹中的所有资源,包括其中子孙文件夹中的所有资源,然后返回到一个Object[]型数组。</para>/// <para>如果该路径是一个文件,则只会加载该文件,并返回到一个Object[]型数组。</para>/// <para>如果没有加载到任何资源,则返回一个没有任何元素的Object[]型数组。</para>/// </summary>/// <param name="path">要加载的文件夹或文件的路径。例如"Prefabs"表示Resources文件夹中的Prefabs文件夹。例如"Prefabs/Cube"表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。</param>public Object[] LoadAll(string path){return Resources.LoadAll(path);}/// <summary>/// <para>同步加载Resources文件夹中指定路径的文件夹中指定类型的所有资源,包括其中子孙文件夹中的该类型的所有资源,然后返回到一个Object[]型数组。</para>/// <para>如果该路径是一个该指定类型的文件,则只会加载该文件,并返回到一个Object[]型数组。</para>/// <para>如果没有加载到任何资源,则返回一个没有任何元素的Object[]型数组。</para>/// </summary>/// <param name="path">要加载的文件夹或文件的路径。例如"Prefabs"表示Resources文件夹中的Prefabs文件夹。例如"Prefabs/Cube"表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。</param>/// <param name="systemTypeInstance">要加载的资源的类型的Type对象。例如typeof(GameObject)表示要加载的资源的类型是GameObject型。</param>public 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 name="T">要加载的资源的类型</typeparam>/// <param name="path">要加载的文件夹或文件的路径。例如"Prefabs"表示Resources文件夹中的Prefabs文件夹。例如"Prefabs/Cube"表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。</param>public T[] LoadAll<T>(string path) where T : Object{return Resources.LoadAll<T>(path);}/// <summary>/// <para>同步把Resources文件夹中指定路径的文件夹及其所有子孙文件夹中所有指定类型的资源添加到一个新建的字典中,并返回该字典。</para>/// <para>应保证Prefabs文件夹中以及它的子孙文件夹中没有重名的资源,如果有重名的,则只会添加找到的第一个资源进字典,其它重名的资源不会进到字典中。</para>/// </summary>/// <typeparam name="T">要加载的资源类型</typeparam>/// <param name="path">资源的路径。例如"Folder/Res"表示Resources文件夹中的Folder文件夹中的Res文件夹</param>public Dictionary<string, T> LoadAllIntoDictionary<T>(string path) where T : Object{Dictionary<string, T> dic = new Dictionary<string, T>();T[] temp = Resources.LoadAll<T>(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 name="T">要加载的资源类型</typeparam>/// <param name="path">资源的路径。例如"Folder/Res"表示Resources文件夹中的Folder文件夹中的Res文件夹</param>/// <param name="dictionary">指定的字典</param>public void LoadAllIntoDictionary<T>(string path, Dictionary<string, T> dictionary) where T : Object{T[] temp = Resources.LoadAll<T>(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 name="path">要加载的资源的路径。例如"Prefabs/Cube"表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。</param>/// <param name="callback">资源加载完毕后要执行的逻辑。参数表示加载的资源。</param>public void LoadAsync(string path, UnityAction<Object> callback = null){MonoManager.Instance.StartCoroutine(LoadAsyncCoroutine(path, callback));}IEnumerator LoadAsyncCoroutine(string path, UnityAction<Object> callback = null){ResourceRequest resourceRequest = Resources.LoadAsync(path);yield return resourceRequest;callback?.Invoke(resourceRequest.asset);}/// <summary>/// <para>异步加载Resources文件夹中指定类型的资源。</para>/// <para>如果有多个相同类型,且相同路径的资源,则只会加载找到的第一个资源。</para>/// </summary>/// <param name="path"></param>/// <param name="type">要加载的资源的类型的Type对象。例如typeof(GameObject)表示要加载的资源的类型是GameObject型。</param>/// <param name="callback">资源加载完毕后要执行的逻辑。参数表示加载的资源。</param>public void LoadAsync(string path, System.Type type, UnityAction<Object> callback = null){MonoManager.Instance.StartCoroutine(LoadAsyncCoroutine(path, type, callback));}IEnumerator LoadAsyncCoroutine(string path, System.Type type, UnityAction<Object> callback = null){ResourceRequest resourceRequest = Resources.LoadAsync(path, type);yield return resourceRequest;callback?.Invoke(resourceRequest.asset);}/// <summary>/// <para>异步加载Resources文件夹中指定类型的资源。</para>/// <para>如果有多个相同类型,且相同路径的资源,则只会加载找到的第一个资源。</para>/// </summary>/// <typeparam name="T">加载的资源的类型</typeparam>/// <param name="path">要加载的资源的路径。例如"Prefabs/Cube"表示Resources文件夹中的Prefabs文件夹中的名叫Cube的资源。</param>/// <param name="callback">资源加载完毕后要执行的逻辑</param>public void LoadAsync<T>(string path, UnityAction<T> callback = null) where T : Object{MonoManager.Instance.StartCoroutine(LoadAsyncCoroutine(path, callback));}IEnumerator LoadAsyncCoroutine<T>(string path, UnityAction<T> callback = null) where T : Object{ResourceRequest resourceRequest = Resources.LoadAsync<T>(path);yield return resourceRequest;callback?.Invoke(resourceRequest.asset as T);}#endregion#region 卸载资源/// <summary>/// <para>异步卸载所有用Resources方式加载到内存中且当前没有被任何地方使用的资源。</para>/// <para>例如要卸载某一个用Resources方式加载的预制体,则必须确保场景中所有这个预制体创建的物体都被销毁了,且这个预制体资源没有赋值给任何脚本中的任何变量。</para>/// <para>如果有,可以把该变量也赋值为null,这样本方法才能成功释放它。</para>/// </summary>/// <param name="callback">资源卸载完毕后执行的逻辑</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 CoroutineTool.WaitForFrame();//资源卸载完毕后执行的逻辑callback?.Invoke();}/// <summary>/// <para>同步卸载指定的资源。</para>/// <para>只能卸载非GameObject类型和Component类型,例如Mesh、Texture、Material、Shader。如果卸载了不让卸载的资源,则会报错。</para>/// <para>如果随后加载的任何场景或资源引用了该资源,将导致从磁盘中加载该资源的新实例。此新实例将与先前卸载的对象相互独立。</para>/// </summary>/// <param name="assetToUnload">要卸载的资源</param>public void UnloadAsset(Object assetToUnload){Resources.UnloadAsset(assetToUnload);}#endregion
}

完结

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

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

http://www.yayakq.cn/news/477086/

相关文章:

  • php企业网站源码 漂亮个人网站备案转公司备案
  • 浙江建设厅网站施工员报名凡客诚品衬衫
  • wdcp网站备份php网站模板制作工具
  • 用什么系统程序做评测网站中装建设为什么不涨
  • 邯郸网站建设策划方案html实例百度网页制作代码
  • 简单公司网站模版正规的网站建设学习网
  • 网站怎么做图片按按钮跳转龙岩网站推广营销
  • 网站建设说明书模板电影网站建设方案
  • 佛山定制网站建设少儿编程加盟品牌有哪些
  • 网站建站费用深圳二手房在售房源量持续增加
  • 建设的网站都是怎么赚钱某男神去年年底来某网站做见面会_竟要求安保人数超过两位数
  • 模板网站下载莱阳有网站建设推广的吗
  • 建网站推广百度热门关键词
  • 论坛创建搜索引擎优化报告
  • 威胁网站检测平台建设wordpress编辑html
  • 网站cms系统 开源it培训机构学费
  • linux建设视频网站苏州360推广网站建设
  • 设计网站建设合同书6酷站 房地产的网站设计参 案例
  • 玉山县建设局的网站wordpress 登录流程
  • 好医生网站怎么做不了题目了莱芜雪野湖天气
  • 公司网站设计好贵州建设项目门户网站
  • 杭州网站建设方案推广网站logo教程
  • 重庆做网站制作的公司站长推荐自动跳转
  • 网站建设明细报价单嵌入式软件开发面试
  • 企业网站开发用什么语言写长春网站建设致电吉网传媒优
  • 商丘做网站公司新站seo快速收录网站内容页设计类专业大学排名
  • 摄影网站建设开题报告北京住总第一开发建设有限公司网站
  • 企业 php网站建设公关服务
  • dede网站qq类文章源码网站的空间和域名备案吗
  • 佛山网站建设培训苏州设计网站建设