Unity大场景切换进行异步加载时,如何设计加载进度条,并配置滑动条按照的曲线给定的速率滑动

请添加图片描述

一、异步加载场景的过程

1、异步加载场景用到的API

LoadSceneAsync

2、异步加载的参数说明

  • (1)默认参数:SceneManagement.LoadSceneAsync(“SceneName”);
AsyncOperation task = SceneManager.LoadSceneAsync("SceneName");
  • (2)异步加载时的两种加载模式-Single和Additive
    请添加图片描述
    关于【活动场景】和【非活动场景】有些什么差异,本文不做讨论。
//定义加载任务
AsyncOperation loadTask = SceneManager.LoadSceneAsync("场景2", LoadSceneMode.Additive);
//AsyncOperation loadTask = SceneManager.LoadSceneAsync("场景2", LoadSceneMode.Single);

await loadTask;                          //实际加载过程
  • (3)Single异步加载的流程
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync("SceneName", LoadSceneMode.Single);

加载的步骤解释:

步骤 进度值 事项描述
第一步 0% ~ 90% 把资源加入到内存中
第二步 初始化新加入的场景,激活新加入的场景,设置为【活动场景】
第三步 新场景激活后,原来的场景会被卸载和清理
第四步 asyncLoad.isDone设置为true 当 isDone 属性为 true 时,表示场景切换已完成,新场景已经完全加载并激活,旧场景已经被卸载。

加载过程:

  • 1、进度值:0%~90% 加载新场景,当到进度值达到90%时,代表场景资源已经加入到内存中,后面10%的时间留给新旧场景的显示切换、新场景初始化、旧场景资源回收。
  • 2、场景要如何切换,【自动显示】还是【代码手动控制】它显示

下面是加载完毕自动显示:

AsyncOperation task = SceneManager.LoadSceneAsync("SceneName");
await loadTask;  

下面是手工控制场景的显示

//定义加载任务
AsyncOperation loadTask = SceneManager.LoadSceneAsync("SceneName");
loadTask.allowSceneActivation = false;   //加载完毕场景不立即显示

await loadTask;                          //实际加载过程

//此处,用户要进行其他操作,比如点击一个按钮,把数据上传到服务器
//...

loadTask.allowSceneActivation = true;    //设置成true后,系统开始后续的10%的工作,会把新场景显示,把老场景卸载

二、大场景切换面临的问题

1、理想情况下的加载

  • (1)、先定义一个Progress的对象(进度报告器),相当于一个事件,当进度值有变化的时候,就会回调该方法。
  • (2)、异步加载资源,并把Progress对象绑定到加载过程。
// 定义进度报告器
var progress = new Progress<float>(value =>
{
   
        
    //更新滑动条进度
    Debug.Log($"加载进度: {
     
     value * 100}%");
});

//实际加载
await SceneManager.LoadSceneAsync("场景2", LoadSceneMode.Single).ToUniTask(progress: progress);   

2、实际加载情况

  • (1)、存在的问题
    要加载的是小场景时,进度报告非常丝滑,一点也不卡顿。
    但是,让要加载的是大场景的时候,update主线程卡死,进度不会走,一直在0%,等几秒钟之后,加载完毕时,进度突然跳成100%,这就太刺激了。
    测试环境说明:Unity2021.3.40

  • (2)、改进方法
    把进度条改成加载前、加载中和加载后,真正的加载放在【加载中】。

三、进度条的设计

(1)如何划分进度条

我们把进度条分成三个部分,如下图的阶段一、二、三。
我们把加载的真正过程放在阶段一和阶段二之间,加载时,进度条暂停不动。
为了看起来丝滑一些,我们把进度条设置曲线动画
在这里插入图片描述

(2)加载效果

请添加图片描述

四、如何给进度条配上曲线动画

如何给滑动条设置曲线动画,如下图所示,在1秒内,让滑块从0%跑到33%,跑的时- 候不匀速,而是先快后慢。

(1)曲线运动速度的设置

public class JumpScene : MonoBehaviour
{
   
   
    /// <summary>
    /// 【第一段进度条动画】的动画曲线
    /// </summary>
    [Header("【第一段进度条动画】的动画曲线")]
    public AnimationCurve startAnim;
    //......
}

在面板上设置曲线速率
在这里插入图片描述

(2)曲线速率与运动的实现:按照给定的曲线速度运动,而不是匀速运动

public async UniTask test4()
{
   
   
    var progress = 0.0f;         //当前累计耗时
    var duration = 3f;           //给定的动画时间,3秒
    var progressCurve = 0f;      //曲线进度,按照曲线速度运动,而不是匀速运动
    while (true)
    {
   
   
        progress += Time.deltaTime;
        progressCurve = startAnim.Evaluate(progress / duration) / duration;            
        Debug.Log(progressCurve);
        if (progress > duration) break;
        await UniTask.Yield();
    }
}

五、主要代码

(1)过程说明

大场景加载的时候,异步加载的进度值会卡死,因为update主线程卡死了
(无论是协程还是用异步,都没有改观,都是卡死状态)。
出现该情况的时候,进度会卡住,直到加载完毕,进度值突然从【0%】调到【90%】,
90%代表资源加载完毕,余下10%的时间是用来进行场景显示和资源回收处理的。
1、前面三分之一:初始化…
2、…实际加载…
3、中间三分之一:假装在加载…
4、后面三分之一:加载后资源处理…实际加载的时候,资源调入完毕时进度

(2)代码清单

/// <summary>
/// 场景跳转:异步加载一个场景,显示进度条,进度条滑动动画
/// 
/// **************************************************************************
/// 大场景加载的时候,异步加载的进度值会卡死,因为update主线程卡死了
/// (无论是协程还是用异步,都没有改观,都是卡死状态)。
/// 出现该情况的时候,进度会卡住,直到加载完毕,进度值突然从【0%】调到【90%】,
/// 90%代表资源加载完毕,余下10%的时间是用来进行场景显示和资源回收处理的。
///   1、前面三分之一:初始化.........
<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值