赞
踩
该功能的aa包是本地包,我这边项目的需求就是将沙盘的多场景在程序初始化的时候将所有场景实例化,不使用动态加载的方式,必然会造成程序运行的设备的负载加大,不过特定的需求就是在切换场景的过程更丝滑(如不用转圈等待)。
如果对使用统一可寻址资产系统(Addressables)还不熟悉的,可以查看我之前写的两篇博客:
Unity3d 使用统一可寻址资产系统(Addressables)入门学习保姆级教程(含工程)
Unity3d 使用统一可寻址资产系统(Addressables)实现服务器资源热更新和资源版本管理等功能(含源码)
我这边使用的版本是Unity3d 2020.3.12f1c1 和 Addressables 1.20.0。不同版本会可能会有一定的效果差异。
#效果
先来看看最终实现后的效果:
实现过程相对比较简单的就是使用协程StartCoroutine的方式Addressables.LoadAssetAsync()加载资源包 ,资源包采用配置数组的方式进行提前配置,并实例化对象在指定节点下面。AsyncOperationHandle的PercentComplete属性来同步更新每个资源的加载进度,并将进度同步到UI的进度条图片和Text上。
UI的搭建较为简单,新建一个图片为进度条,将Image Type设置为Filled,FillMathod 设置为Horizontal,Fill Origin设置为 Left:
这样设置后我们只需要修改Fill Amount就是进度条的进度了。
然后再新建两个Text作为加载的提示和加载的进度即可:
关于场景包的处理,我这里是对场景的节点进行了拖拽成了预设prefab文件,然后将prefab文件添加到Addressables对应的组中,进行Addressables打包即可,这些操作已经在之前的两篇博客中有详细的介绍,这里就不介绍了。
要注意的是在Hierarchy窗口中关联的prefab节点要进行删除,为了防止误操作,最好进行版本管理(svn 或者 git)。
这里我们新建了AA包的配置类如下:
[System.Serializable]
public class AAPack
{
public string NodeName;
public Transform ParentTran;
public Vector3 scale = Vector3.one;
}
NodeName为aa包名,在Addressables Groups窗口对应填写的包名:
ParentTran为实例化到该节点的子节点,scale 为实例化后的缩放配置;可以自行添加其他配置项,如实例化的位置(position),实例化的旋转角度(eulerAngles),新增的其它配置项需要在实例化的时候新增对应参数的设置。
这里的aa包配置,我设置为数组,并将对应的需要加载的包配置如下:
先贴出加载和更新进度UI的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class AAPackLoader : MonoBehaviour
{
public AAPack[] AAPacks;
public Image ProcessImg;
public Text ProcessText;
int NowIdx = 0;
float TotalRat = 0;
// Start is called before the first frame update
void Start()
{
transform.localScale = Vector3.one;
ProcessImg.fillAmount = 0;
ProcessText.text = "0%";
StartCoroutine(LoadAllAAPack());
}
AsyncOperationHandle<GameObject> AO;
IEnumerator LoadAllAAPack() {
for (int i = 0; i < AAPacks.Length; i++) {
NowIdx = i;
if (AAPacks[i] != null)
{
AO = Addressables.LoadAssetAsync<GameObject>(AAPacks[i].NodeName);
yield return AO;
if (AO.Status == AsyncOperationStatus.Succeeded)
{
GameObject go = Instantiate(AO.Result, Vector3.zero, Quaternion.identity);
go.name = AAPacks[i].NodeName;
go.transform.SetParent(AAPacks[i].ParentTran == null ? this.transform : AAPacks[i].ParentTran);
go.transform.localPosition = Vector3.zero;
go.transform.localEulerAngles = Vector3.zero;
go.transform.localScale = AAPacks[i].scale;
go.SetActive(true);
}
}
}
transform.localScale = Vector3.zero;
Destroy(gameObject);
}
// Update is called once per frame
void Update()
{
if (AAPacks.Length > 0) {
//+1
TotalRat = (float)(NowIdx) / (float)AAPacks.Length + AO.PercentComplete / AAPacks.Length; //AO.GetDownloadStatus().Percent
//Debug.Log("NowIdx:" + NowIdx + " TotalRat:" + TotalRat + " AAPacks:" + AAPacks.Length + " Percent:" + AO.PercentComplete);
ProcessImg.fillAmount = TotalRat;
ProcessText.text = (TotalRat * 100).ToString("F1") + "%";
}
}
}
这里启动时直接开始了协程IEnumerator LoadAllAAPack进行所有包的加载,并在Update函数中对进度进行了换算和更新。在加载完成后,直接销毁了该对象,因为这个模块在程序启动时,加载了所有的场景,它的工作已经完成了,不会再执行了,所以进行了销毁。
接下来直接将需要关联的节点拖拽进入对应的框内:
并运行即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。