1- 如何使用新的资产包统一系统加载主要资产,而我的资产包具有任何类型的游戏对象,例如:sprite、obj、声音、视频等。
您必须使用通用函数,例如:
MyAssetHelper {
public static T Load<T>(string bundle, string asset) {
return SomeT;
}
}
我们必须完成这个函数的编写,它不会返回这样的方法,但目前只需将其视为从给定捆绑包中请求给定资产的方法,您所关心的是你得到了一些回报。
2- 我不知道如何实例化加载的资产?
我们将通过修改我们的函数来获取更多参数来做到这一点,OnLoad 我们希望在我们想要的资产最终在内存中并且可用时发生,以及 OnLoadFailed 在 oops 时调用,坏事发生了。我们不知道加载捆绑包和/或加载资产需要多长时间,因此我们必须等待并依赖回调。
MyAssetHelper {
public static void Load<T>(string bundle, string asset, UnityAction<T> OnLoad, UnityAction OnLoadFailed) where T : UnityEngine.Object {
T obj;
//get the object somehow
if(obj != null) OnLoad.Invoke(obj); //we have an object
else OnLoadFailed.Invoke(); //something failed!
}
}
现在,您必须指定调用函数时想要的类型(无论如何您之前都需要它,但您总是使用GameObject)以及加载事物时的回调函数(或者它们失败)。
那么,如何调用它的一个例子:
public void LoadASprite() { //arbitrary function, could be Start
MyAssetHelper.Load<Sprite>( //the above function in a static class
"bundle","sprite_asset", sprite => { //anonymous lambda expression (success)
Debug.Log("We loaded a sprite! " + sprite);
}, () => { //anonymous lambda expression (failure)
Debug.Log("Failed to load sprite!");
}
);
}
根据您要加载的类型,您需要对它做不同的事情,实例化它,将它分配给一个字段,等等。失败时,您可能想要打印某种消息。在运行时,您可能想要假设捆绑包总是成功(“我知道我会将它们一起发送”)或向用户显示一条消息(“下载捆绑包失败,请检查您的连接”)。由你决定。你甚至可以让OnLoadFail 函数接受一个字符串参数,这样你就可以提供更多信息(因为我们将从多个地方调用它)。
不过,现在我们必须完成写出我们实际的加载方法。我们已经模板化了它所需要的外观(接受一个包名称、一个资产名称,并具有两个回调函数),但我们仍然需要进行实际加载。
我们知道它不会马上返回(这就是我们创建回调的原因),所以我们需要将我们的内容转移到一个新方法,这将是一个协程,所以我们需要启动那个协程。
MyAssetHelper {
public static void Load<T>(string bundle, string asset, UnityAction<T> OnLoad, UnityAction OnLoadFailed) where T : UnityEngine.Object {
StartCoroutine(DoLoad(bundle, asset, OnLoad, OnLoadFailed));
}
private IEnumerator DoLoad(string bundlePath, string assetName, UnityAction<T> OnLoad, UnityAction OnLoadFailed);
T obj;
yield return null; //operational bundle loading goes here
if(obj != null) OnLoad.Invoke(obj); //we have an object
else OnLoadFailed.Invoke(); //something failed!
}
}
下一位将替换DoLoad 中的那四行,因为它的块将相当大,只是想确保了解处理协程的添加层。下面发生的所有事情是我们请求加载一个资产包,当它完成时,我们必须从包中请求一个资产,当完成时,调用OnLoad.Invoke(obj)。在每一步,如果出现梨形问题,请致电OnLoadFailed.Invoke()。
string path = Path.Combine(Application.persistentDataPath,bundlePath);
if (File.Exists(path)) { //load asset from local computer (in Unity's persistent data directory)
AssetBundleCreateRequest bundleRequest = AssetBundle.LoadFromFileAsync(path);
yield return bundleRequest;
AssetBundle bundle= bundleRequest.assetBundle;
if (bundle == null) {
OnLoadFailed.Invoke();
return;
}
}
else {
OnLoadFailed.Invoke();
return;
}
AssetBundleRequest assetRequest = bundle.assetBundle.LoadAssetAsync<T>(assetName);
yield return assetRequest;
if (null != assetRequest.asset) {
onLoad?.Invoke((T)assetRequest.asset);
}
else {
onLoadFail?.Invoke();
}
请务必查看the documentation,了解有关在代码中获取或使用资产包的更多详细信息,包括如何从远程位置下载以及Application 类,了解有关persistentDataPath 和相关路径的详细信息。