Unity3D:动态加载资源(Resources.Load与AssetBundle.LoadAsset)

Unity3D动态加载一(Resources)


  1. 在Unity3D中Project视窗中创建文件夹:Resources。
  2. 将需要动态加载的文件放入其中,例如Texture,Sprite,prefab等等。
  3. 在脚本中调用API接口Resources.Load()相关接口即可。

例如:

using UnityEngine;
using UnityEngine.UI;
public class LoadTest1:MonoBehaviour
{
	private void Start()
	{
		Sprite sp=Resources.Load<Sprite>("Pic");  //"Pic"是资源的名字
		GameObject obj=Resources.Load<GameObject>("Prefab01"); 
		Instantiate(obj);
	}
}

此种方式只能访问Resources文件夹下的资源。


Unity3D动态加载二


第二种方式就是使用AssetBundle(AssetBundle是一个资源的集合,可以是Unity3D所支持的任何资源格式)。

创建AssetBundle文件

  • 从Project视图中选择要打包AssetBundle的资源。
  • 在Inspector视图的最底部可以看到分配AssetBundle和变体的部分
  • 选择左边下拉选择分配AssetBundle。其中显示“None”,点击“New…”以创建新的AssetBundle,并输入相应的名字。若要添加子文件夹,可以在名字中用“/”分隔。
  • 用脚本进行构建AssetBundle
  • 在Assets(Project视窗)文件夹下创建Editor文件夹,创建脚本CreateAssetBundles.cs
using UnityEditor;

public class CreateAssetBundles
{
  [MenuItem("AB/Build AssetBundles")]
  static void BuildAllAssetBundles()
  {
  	//要创建的目录
  	string assetBundleDirectory = "Assets/AssetBundles";
  	if(!Directory.Exists(assetBundleDirectory))
  	{
  		Directory.CreateDirectory(assetBundleDirectory);
  	}
  	//三个参数:第一个是创建的目录位置,第二个是AssetBundle的压缩方式,第三个是创建的平台。
  	BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
  }
}
  • 保存好脚本后,回到Unity3D,上方工具栏会出现“AB”选项卡,点击后选择“Build AssetBundles”即可完成AssetBundle的构建。

构建好后输出目录中会多出一个与目录名相同的AssetBundle文件和他的manifest文件;然后其余你每分配的一个AssetBundle对应一个文件和同名的manifest文件。

加载AssetBundle文件

  • 从本地加载AssetBundle资源(LoadFromFile)
using UnityEngine;
public class LoadTest02:MonoBehaviour
{
	private void Start()
	{
		string path=Application.dataPath+"/AssetBundles/"+"roles";  //最后一个字符串是AssetBundle的名字
		AssetBundle assetBundle=AssetBundle.LoadFromFile(path);
		if(assetBundle==null)
		{
			return;
		}
		GameObject obj=assetBundle.LoadAsset<GameObject>("Role01"); //字符串是AssetBundle中资源名称
		Instantiate(obj);
	}
}
  • 从本地加载AssetBundle(LoadFromMemory)
 using UnityEngine;
 using System.IO;
public class LoadTest02:MonoBehaviour
{
	private void Start()
	{
		string path=Application.dataPath+"/AssetBundles/"+"roles";  //最后一个字符串是AssetBundle的名字
		AssetBundle assetBundle=AssetBundle.LoadFromMemory(File.ReadAllBytes(path));
		if(assetBundle==null)
		{
			return;
		}
		GameObject obj=assetBundle.LoadAsset<GameObject>("Role01"); //字符串是AssetBundle中资源名称
		Instantiate(obj);
	}
}

此方法与LoadFromFile相比只是将path换成了File.ReadAllBytes(path),即LoadFromMemory的参数是接受的一个字节数组,可以用任何AssetBundle的字节数组替换File.ReadAllBytes()。

  • 远程或本地加载AssetBundle (UnityWebRequest)
using UnityEngine;
using UnityEngine.Networking;
using System.IO;
public class LoadTest03:MonoBehaviour
{
	private void Start()
	{
		StartCoroutine(LoadFromRemote());
	}
  	private IEnumerator LoadFromRemote()
  	{
  		string path="D:/Documents/ABRep/roles";
  		string uri="file:///"+path;  //可将uri换成任何相关的AssetBundle服务器
  		UnityWebRequest reques=UnityWebRequestAssetBundle.GetAssetBundle(uri,0);
  		yield return request.SendWebRequest();
  		AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);
  		GameObject obj= bundle.LoadAsset<GameObject>("Role02");
  		Instantiate(obj);
  	}
}

以上都是使用通本方法,还有对应的异步方法LoadFromFileAsync,LoadFromMemoryAsync等

扩展:关于版本更新便是使用AssetBundle。通过自定义相关的Version.txt版本文件,每次打开游戏便从远程服务器拉取最新的Version.txt,对比之后,进行扩展包(AssetBundle资源)的下载。之后再谈谈下载相关的问题。

发布了10 篇原创文章 · 获赞 11 · 访问量 1798

猜你喜欢

转载自blog.csdn.net/qq_34406755/article/details/104071017