跳到主要内容

资源加载

学习资源加载的使用方法。

方法列表

  • LoadSceneAsync() 异步加载场景
  • LoadAssetSync() 同步加载资源对象
  • LoadAssetAsync() 异步加载资源对象
  • LoadSubAssetsSync() 同步加载子资源对象
  • LoadSubAssetsAsync() 异步加载子资源对象
  • LoadAllAssetsSync() 同步加载资源包内所有资源对象
  • LoadAllAssetsAsync() 异步加载资源包内所有资源对象
  • LoadRawFileSync() 同步获取原生文件
  • LoadRawFileAsync() 异步获取原生文件

统一约定

Location为资源的定位地址,也是加载资源对象的唯一标识符。

  • 在未开启可寻址模式下,location代表的是资源对象的完整路径。
// 以工程内的音频文件为例:"Assets/GameRes/Audio/bgMusic.mp3" 
package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic");
  • 在开启可寻址模式下,location代表的是资源对象可寻址地址。

    注意:可寻址模式下,也支持使用完整的资源路径来加载。

// 以工程内的音频文件为例:"Assets/GameRes/Audio/bgMusic.mp3" 
// 需要在资源配置界面启用可寻址功能(Enable Addressable)。
// 配置界面的可寻址规则为AddressByFileName,那么资源定位地址填写文件名称:"bgMusic"
package.LoadAssetAsync<AudioClip>("bgMusic");

加载路径的匹配

// 不带扩展名的模糊匹配
package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic");

// 带扩展名的精准匹配
package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic.mp3");

异步加载范例

// 委托加载方式
void Start()
{
AssetHandle handle = package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic.mp3");
handle.Completed += Handle_Completed;
}
void Handle_Completed(AssetHandle handle)
{
AudioClip audioClip = handle.AssetObject as AudioClip;
}
// 协程加载方式
IEnumerator Start()
{
AssetHandle handle = package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic.mp3");
yield return handle;
AudioClip audioClip = handle.AssetObject as AudioClip;
}
// Task加载方式
async void Start()
{
AssetHandle handle = package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic.mp3");
await handle.Task;
AudioClip audioClip = handle.AssetObject as AudioClip;
}

资源句柄释放

IEnumerator Start()
{
// 资源句柄释放可以减少该资源的引用计数,当资源引用计数为零的时候,可以使用资源卸载方法卸载资源包。
AssetHandle handle = package.LoadAssetAsync<AudioClip>("Assets/GameRes/Audio/bgMusic.mp3");
yield return handle;
...
handle.Release();
}

资源卸载范例

// 卸载所有引用计数为零的资源包。
// 可以在切换场景之后调用资源释放方法或者写定时器间隔时间去释放。
private void UnloadUnusedAssets()
{
var package = YooAssets.GetAssetsPackage("DefaultPackage");
package.UnloadUnusedAssets();
}

// 尝试卸载指定的资源对象
// 注意:如果该资源还在被使用,该方法会无效。
private void TryUnloadUnusedAsset()
{
var package = YooAssets.GetAssetsPackage("DefaultPackage");
package.TryUnloadUnusedAsset("Assets/GameRes/Panel/login.prefab");
}

// 强制卸载所有资源包,该方法请在合适的时机调用。
// 注意:Package在销毁的时候也会自动调用该方法。
private void ForceUnloadAllAssets()
{
var package = YooAssets.GetAssetsPackage("DefaultPackage");
package.ForceUnloadAllAssets();
}

// 通过初始化配置资源释放行为
class InitializeParameters
{
/// <summary>
/// 自动销毁不再使用的资源提供者
/// </summary>
public bool AutoDestroyAssetProvider = false;
}

预制体加载范例

IEnumerator Start()
{
AssetHandle handle = package.LoadAssetAsync<GameObject>("Assets/GameRes/Panel/login.prefab");
yield return handle;
GameObject go = handle.InstantiateSync();
Debug.Log($"Prefab name is {go.name}");
}

子对象加载范例

例如:通过TexturePacker创建的图集,如果需要访问图集的精灵对象,可以通过子对象加载接口。

IEnumerator Start()
{
SubAssetsHandle handle = package.LoadSubAssetsAsync<Sprite>(location);
yield return handle;
var sprite = handle.GetSubAssetObject<Sprite>("spriteName");
Debug.Log($"Sprite name is {sprite.name}");
}

资源包内所有对象加载范例

例如:我们将所有配置表打进了一个资源包里,我们想把所有配置文件一次性全部加载出来解析。

IEnumerator Start()
{
// 注意:location只需要填写资源包里的任意资源地址。
AllAssetsHandle handle = package.LoadAllAssetsAsync<UnityEngine.TextAsset>(location);
yield return handle;
foreach(var assetObj in handle.AllAssetObjects)
{
UnityEngine.TextAsset textAsset = assetObj as UnityEngine.TextAsset;
}
}

场景异步加载范例

注意:当加载新的主场景的时候,会自动释放之前加载的主场景以及附加场景。

IEnumerator Start()
{
string location = "Assets/GameRes/Scene/Login";
var sceneMode = UnityEngine.SceneManagement.LoadSceneMode.Single;
bool suspendLoad = false;
SceneHandle handle = package.LoadSceneAsync(location, sceneMode, suspendLoad);
yield return handle;
Debug.Log($"Scene name is {handle.Scene.name}");
}

原生文件加载范例

注意:原生文件必须使用原生构建管线来构建。

例如:wwise的初始化文件

IEnumerator Start()
{
// 注意:该Package必须是原生文件构建管线构建的资源包裹。
string location = "Assets/GameRes/wwise/init.bnk";
RawFileHandle handle = package.LoadRawFileAsync(location);
yield return handle;
byte[] fileData = handle.GetRawFileData();
string fileText = handle.GetRawFileText();
string filePath = handle.GetRawFilePath();
}

配置文件加载范例

// 自定义的配置文件
public class MyGameConfig: ScriptableObject
{
...
}

IEnumerator Start()
{
string location = "Assets/GameRes/config/gameConfig.asset";
AssetHandle handle = package.LoadAssetFileAsync(location);
yield return handle;
MyGameConfig gameCOnfig = handle.AssetObject as MyGameConfig;
}

获取资源信息列表

通过资源标签来获取资源信息列表。

void GetAssetInfosByTag(string tag)
{
AssetInfo[] assetInfos = package.GetAssetInfos(tag);
foreach (var assetInfo in assetInfos)
{
Debug.Log(assetInfo.AssetPath);
}
}

检测资源是否需要更新下载

{
bool isNeedDownload = package.IsNeedDownloadFromRemote(location);
}