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的文件夹,它们可以放在Assets文件夹中的任意位置,使用Resources的方法加载时,将对每个Resources文件夹进行查找。
注意:如果一个项目中有多个Resources文件夹,则应确保里面的文件的相对路径不重复,如果重复,则使用Resources.Load方法加载时,只会加载找到的第一个该名字的文件。
在同一个文件夹中,文件名不要重名,如果实在要重名,则加载时要使用泛型加载指定的类型。
使用Resources.Load或者Resources.LoadAll加载时,路径是从Resources文件夹里面的文件夹开始的,例如Resources文件夹里有一个Audio文件夹,Audio文件夹里面也有一个Music文件夹,Music文件夹有一个叫做Song的.mp3文件,则路径是"Audio/Music/Song"
路径中的文件名末尾一定不要写后缀,写了后缀反而加载不成功。
路径可以用反斜杠来写。"Audio/Music/Song"可以写成:
"Audio\\Music\\Song"
或者
@"Audio\Music\Song"
不建议路径用反斜杠来写,建议统一都用正斜杠来写。
Resources.Load(string 要加载的资源的路径)
返回值是Object型。
同步加载Resources文件夹中的资源。
如果有多个相同路径的资源,则只会返回找到的第一个资源。
Resources.Load(string 要加载的资源的路径, System.Type 要加载的资源的类型的Type对象)
返回值是Object型。
同步加载Resources文件夹中的指定类型的资源。
如果有多个相同类型,且相同路径的资源,则只会返回找到的第一个资源。
或者使用函数重载指定类型:
GameObject go = Resources.Load("Prefabs/Cube",typeof(GameObject)) as GameObject;
Resources.Load<要加载的资源的类型>(string 要加载的资源的路径)
返回值是要加载的资源的类型。
同步加载Resources文件夹中的指定类型的资源。
如果有多个相同类型,且相同路径的资源,则只会返回找到的第一个资源。
Resources.LoadAll(string 要加载的资源的文件夹路径或文件路径)
返回值是Object[]型。
同步加载Resources文件夹中指定路径的文件夹中的所有资源,包括其中子孙文件夹中的所有资源,然后返回到一个Object[]型数组。
如果该路径是一个文件,则只会加载该文件,并返回到一个Object[]型数组。
如果没有加载到任何资源,则返回一个没有任何元素的Object[]型数组。
Resources.LoadAll(string 要加载的资源的文件夹路径或文件路径,System.Type 要加载的资源的类型的Type对象)
返回值是Object[]型。
同步加载Resources文件夹中指定路径的文件夹中的指定类型的所有资源,包括其中子孙文件夹中的该类型的所有资源,然后返回到一个Object[]型数组。
如果该路径是一个该指定类型的文件,则只会加载该文件,并返回到一个Object[]型数组。
如果没有加载到任何资源,则返回一个没有任何元素的Object[]型数组。
Resources.LoadAll
同步加载Resources文件夹中指定路径的文件夹中的指定类型的所有资源,包括其中子孙文件夹中的该类型的所有资源,然后返回到一个Object[]型数组。
如果该路径是一个该指定类型的文件,则只会加载该文件,并返回到一个Object[]型数组。
如果没有加载到任何资源,则返回一个没有任何元素的Object[]型数组。
Resources.LoadAsync(string 要加载的资源的路径,UnityAction
if (GUI.Button(new Rect(150,0,150,80),"异步加载单个资源"))
{
StartCoroutine(LoadAsyncCoroutine());
}
IEnumerator LoadAsyncCoroutine()
{
//开始异步加载
ResourceRequest resourceRequest = Resources.LoadAsync("Prefabs/Cube");
//等待资源加载完毕
yield return resourceRequest;
//加载成功加载的资源--资源加载完毕后执行的逻辑
Instantiate(resourceRequest.asset);
}
Resources.LoadAsync(string 要加载的资源的路径,System.Type 要加载的资源的Type对象,UnityAction
Resources.LoadAsync<要加载的资源的类型>(string 要加载的资源的路径,UnityAction<要加载的资源的类型> 资源加载完毕后要执行的逻辑)
返回值是ResourceRequest类型。
一般配合协程来使用。在协程中可以使用yield return来等待资源加载。
异步加载Resources文件夹中指定类型的资源。
如果有多个相同类型,且相同路径的资源,则只会加载找到的第一个资源。
回调的参数就是加载的资源。
经用Resources.Load、Resources.LoadAsync、Resources.LoadAll加载的资源,即使在场景中没有使用,它们也会占用内存,此时要释放它们,就可以使用Resources.UnloadUnusedAssets方法和Resources.UnloadAssets方法。
Resources.UnloadUnusedAssets
返回值是AsyncOperation型。
异步卸载所有用Resources方式加载到内存中且当前没有被任何地方使用的资源。
可以配合协程使用。
例如要卸载某一个用Resources方式加载的预制体,则必须确保场景中所有这个预制体创建的物体都被销毁了,且这个预制体资源没有赋值给任何脚本中的任何变量。
如果有,可以把该变量也赋值为null,这样本方法才能成功释放它。
Resource.UnloadAsset(Object 要卸载的资源)
无返回值。
卸载指定的资源。
只能卸载非GameObject类型和Component类型,例如Mesh、Texture、Material、Shader。如果卸载了不让卸载的资源,则会报错。
如果随后加载的任何场景或资源引用了该资源,将导致从磁盘中加载该资源的新实例。此新实例将与先前卸载的对象相互独立。
Resources.FindObjectsOfTypeAll<要查找的类型>()
把已加载的指定类型的对象返回成指定类型的数组。
包括但不限于游戏对象、预制件、材质、网格、纹理等。
此方法还把Unity内部对象返回到该数组中,因此请小心处理返回的对象。
只要对象是指定的类型的,且已经加载了它,即使它是被禁用,也会被返回到该数组。
Resources.FindObjectsOfTypeAll(Type 要查找的类型的Type对象)
把已加载的指定类型的对象返回成Object[]型的数组。
包括但不限于游戏对象、预制件、材质、网格、纹理等。
此方法还把Unity内部对象返回到该数组中,因此请小心处理返回的对象。
只要对象是指定的类型的,且已经加载了它,即使它是被禁用,也会被返回到该数组。
Resources.InstanceIDToObject(int 对象的实例ID)
返回值是Object型。
根据对象的实例ID返回该对象。
对象的实例ID可以通过 对象.GetInstanceID() 获取。
同步:做一件事情,完成之后,再做下一件事情。事情必须做完一件再做另一件。
异步:做一件事情,开始做的时候,不等事情做完,就立即开始做下一件事情。多件事情可以一起做。
同步和异步最大的区别在于:同步会阻塞主线程,异步不会阻塞主线程。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
///
/// 资源管理器
///
public class ResourcesManager : SingletonPatternBase
{
///
/// 异步加载Resources文件夹中指定类型的资源
///
public void LoadAsync(string path,UnityAction callback = null) where T:Object
{
MonoManager.Instance.StartCoroutine(LoadAsyncCoroutine(path, callback));
}
IEnumerator LoadAsyncCoroutine(string path, UnityAction callback = null) where T : Object
{
//开始加载资源
ResourceRequest resourceRequest = Resources.LoadAsync(path);
//等待资源加载完毕
yield return resourceRequest;
//执行资源加载完毕后的动作
callback?.Invoke(resourceRequest.asset as T);
}
///
/// 异步卸载资源,往往在切换场景的时候使用
///
///
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();
}
}