Unity异步加载小心得

背景

一般体量的游戏都会有多个场景,其中主场景资源会相对较多,假如使用直接加载的方式加载主场景,就会出现卡顿的现象,这对玩家来说不是好的体验.由此加载该类场景最好使用异步加载,通过异步加载给出加载进度提示,优化场景过渡的体验.

先上效果

在这里插入图片描述

可以看出来,异步加载提示进度,同步加载直接卡在哪里.

上代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class LoadAsyncScene : MonoBehaviour
{

    //异步操作对象
    private AsyncOperation asyncOperation;
    [Tooltip("加载进度文本")]
    public Text progress;
    [Tooltip("加载进度数值")]
    float progressValue = 0;
    [Tooltip("加载进度条图片")]
    public Image progressBar;
    [Tooltip("下个场景的名字")]
    public string Scene_name;

    private void Start()
    {
        Invoke("AsyLoad", 0.1f);//延后0.1秒执行异步,必须的
        // AsyLoad();//直接异步会有问题
    }

    void AsyLoad()
    {
        StartCoroutine("LoadScene", Scene_name);   // 开启协程
    }

    /// <summary>
    /// 通过协程加载场景
    /// </summary>
    /// <param name="Scene_name">加载的场景名称</param>
    /// <returns></returns>
    IEnumerator LoadScene(string Scene_name)  
    {
        asyncOperation = SceneManager.LoadSceneAsync(Scene_name);//异步跳转到Scene_name场景 
        asyncOperation.allowSceneActivation = false;//当game场景加载到90%时,不让它直接跳转到game场景。 
        yield return asyncOperation;
    }
    void Update()
    {
        if (asyncOperation == null) { return; }
        progressValue = asyncOperation.progress;

        if (asyncOperation.progress >= 0.9f)

        {
            //值最大为0.9
            progressValue = 1.0f;
        }

        //为滑动条赋值

        if (progressValue != progressBar.fillAmount)//进度条的值还没到给定值

        {
            progressBar.fillAmount = Mathf.Lerp(progressBar.fillAmount, progressValue, Time.deltaTime*2);//不断往前加载,插值加载

            if (Mathf.Abs(progressBar.fillAmount - progressValue) < 0.01f)//进度条和给定值很接近了

            {

                progressBar.fillAmount = progressValue;

            }
        }

        progress.text = ((int)(progressBar.fillAmount * 100)).ToString() + "%";

        if ((int)(progressBar.fillAmount * 100) == 100)//进度条到了100%才允许跳
        {

            //允许异步加载完毕后自动切换场景
            // if (Input.anyKeyDown)
            asyncOperation.allowSceneActivation = true;
        }
    }
}


分析

1.异步加载执行需要注意时机

Invoke(“AsyLoad”, 0.1f);//延后0.1秒执行异步,必须的
,这个延后时间,可以浮动, 但不可直接在Start中开启,如果直接开启会出现很多问题.哪些问题呢?
①进度条不正常显示
②跳转的场景不受asyncOperation.allowSceneActivation = false;的控制
这不是我们想看到的,所有,异步加载一定要延后一点点执行.

2. 注意返回异步操作对象

在 IEnumerator 中使用yield return asyncOperation;返回该异步对象,外界通过asyncOperation的相关参数来执行进度.

3.加载显示值需要做处理

progressBar.fillAmount该值是表示异步场景加载进度值得,但是它不是真正的异步,在当前线程里,也是每一帧才能收到一次progressBar.fillAmount传过来的值,所以progressBar.fillAmount的值,很大可能是跳跃的不连续的.当前这一帧得到值为0.03,下一帧就到了0.25,这之间跨度很大,如果我们的进度条显示数据直接从progressBar.fillAmount来,那进度条呈现的状态也会是一卡一卡的.所以我们做进度条显示的数值是先经过处理的, progressBar.fillAmount = Mathf.Lerp(progressBar.fillAmount, progressValue, Time.deltaTime*2);//不断往前加载,插值加载
使用插值是个不错的方法.

4.通过属性值来控制是否能自动跳转到下一场景

asyncOperation.allowSceneActivation = false;//当game场景加载到90%时,不让它直接跳转到game场景。
当 asyncOperation.allowSceneActivation = false时,asyncOperation.progress的值最多加载到0.9,就会停下,如果不做其他操作,场景就会停在这里,无法跳转,想要跳转,就得把asyncOperation.allowSceneActivation =true; 这样场景才能自动跳转.

5.让asyncOperation.allowSceneActivation =true的时机

注意asyncOperation.allowSceneActivation =true可不是任何时候都行,这样能避免 进度条显示还未到100%就跳转的现象,应该等到进度条达到100%再赋值为 true;

 if ((int)(progressBar.fillAmount * 100) == 100)//进度条到了100%才允许跳
        {

            //允许异步加载完毕后自动切换场景
            // if (Input.anyKeyDown)
            asyncOperation.allowSceneActivation = true;
        }
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值