前言
Unity资源的加载的方式
1、Resources.Load,unity缺省的加载资源方式,就是默认的(只能加载Resources目录中的资源)
Exp:
//Prefabs/UIPanel/xx为Resources下面的文件路径
GameObject ab = Resources.Load<GameObject>("Prefabs/UIPanel/xx");
2、把资源打包成Assetbundle包
3、使用AssetDataBase来加载(只有在editor中才可以用的API)
Exp:
//Assets/Art/UI/xx.png相对路径,注意:一定要带上文件后缀名
Sprite item = AssetDatabase.LoadAssetAtPath<Sprite>("Assets/Art/UI/xx.png");
4、WWW方式(目前已经被废除了)
private void LoadAssetWWW()
{
StartCoroutine(WWWLoad());
}
private IEnumerator WWWLoad()
{
//url 需要下载的资源的url地址
WWW www = new WWW("url");
yield return www;
if(www.isDone)
{
var data = www.bytes;
//然后读取bytes把数据转换为我们需要的类型
}
}
但是这种方式在2018之后就被废除了,由下面UnityWebRequest替代
5、UnityWebRequest方式
private IEnumerator WebRequestLoad()
{
//url 需要下载的资源的url地址
UnityWebRequest request = UnityWebRequest.Get("url");
yield return request.SendWebRequest();
Debug.Log(request.downloadHandler.data);
//然后读取data把数据转换为我们需要的类型
}
正文(资源热更新)
为了实现资源的热更新,会把资源打成AssetBundle资源包,然后放到服务器上面,客户端从服务器拿资源。
如果AB资源过大,从服务器下载时,有可能会流失掉一部分用户,所以要权衡一下是不是需要把所有的资源都放到远程服务器上面。
目前比较常用的方案是可以放一部分在本地,一部分放在服务器,但是这样做会导致的问题是,如果后期放在本地的资源发生了变化需要作为热更资源更新。
这样就会出现,游戏内会存在两份资源,所以这个具体要看项目怎么制定合适的方案
1、给资源设置AB名字
注意:ab名字也可以包含/等特殊字符,如果文件名字相同,但是在不同文件夹下面也不会有冲突
2、使用Unity的API来打包生成AB
BuildPipeline.BuildAssetBundles(string outputPath, AssetBundleBuild[] builds, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);
各个参数的讲解
①outputPath:生成AB包的存放路径
②builds:所有设置了AB包名字的文件
③assetBundleOptions:打包压缩的方式
BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是加载时间更长。使用之前需要整体解压。一旦被解压,这个包会使用LZ4重新压缩。
使用资源的时候不需要整体解压。在下载的时候可以使用LZMA算法,一旦它被下载了之后,它会使用LZ4算法保存到本地上。
BuildAssetBundleOptions.UncompressedAssetBundle:不压缩资源,包体大,加载快
BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率比LZMA低,但是我们可以加载指定资源而不用解压全部资源
LZ4压缩,跟不压缩的加载速度差不多,而且比不压缩文件要小,一般都会选择使用LZ4压缩!
3、把AB包放到服务器上面
从服务器下载下来的AB资源一般都会放在永久性目录下面。
问题:如果一个AB资源发生变化了,下次进入游戏时,怎么知道这个资源发生变化了,并且重新下载呢
常用的方案:打包AB资源时,都会对应生成一个Manifest文件,我们会根据这个文件的内容来生成Md5码。为什么用这个Manifest文件呢,因为如果这个文件没发生任何变化的话,相应的这个Manifest内容也不会发生任何变化,反之,会生成新的Md5码,我们只要拿本地的文件跟服务器的文件的Md5码做比对,如果发生变化就重新下载!