当前位置:首页 » 《随便一记》 » 正文

Unity 异步_不会三刀流的索隆的博客

10 人参与  2021年11月19日 17:23  分类 : 《随便一记》  评论

点击全文阅读


异步

C# 异步

因为同步进程会出现阻塞的情况,为了避免卡顿,以及在处理数据时仍然可以接收用户新的访问,异步的思想就出现了

异步可以理解为,在调用异步函数的时候,函数会直接返回,然后剩下的部分等同于在一个新线程中运行

异步操作的关键字是asnycawait,当一个方法具有 async 的签名时, 它会向编译器发出信号,说明此方法包含 await 语句;也包含异步操作。

windows官方定义:

异步操作后跟同步操作的这种组合是一个异步操作。 换言之,如果操作的任何部分是异步的,整个操作就是异步的。

Unity 异步

Unity还提供了一系列的异步操作,方便大家根据需要进行选择。这些异步操作包括Resources的加载、场景的加载、Asset Bundle的加载、NavMesh的生成等等。当然,这些异步操作的底层实现各不相同。有些是独立线程处理的,有些则是利用Unity内部的JobSystem,也有一些是二者结合使用的。

在Unity中使用协程搭配异步来写代码更佳,例如通过异步加载场景,在加载过程中通过每帧更新进度条给予玩家一个反馈,就可以在协程中调用异步加载场景的方法,然后暂停协程,等待当前一帧结束,然后更新进度条,反复之后,就完成进度条显示进度加载场景的效果。

这里有四点需要注意:

  1. 首先创建一个unity自定义AsyncOperation类的对象,来承接unity异步加载场景的返回值,这里的返回值就是刚才的那个AsyncOperation类,作用是管理异步加载的进度,以及操控加载完毕后场景是否显示
  2. 通过yield return new WaitForEndOfFrame()达到协程的一个暂停,不然很快进度条就跑过去了,可能这个时候场景数据还没有加载完
  3. 异步加载场景函数调用一次就好,调用多次的话,出现bug先不说,如果所要加载的场景特别大的话,估计CPU就报废了(开个玩笑),所以在调用完异步之后,要做一个标记,循环再进来之后不进入异步的语句
  4. 因为加载场景,有可能在进度条还没有走完之前,场景就加载好了,所以要保证场景加载完毕之后场景不显示,需要用到ao.allowSceneActivation = false;语句,当然,在进度条加载完成之后,调用ao.allowSceneActivation = false;语句显示所加载的场景

代码如下:

public class Loading : MonoBehaviour 
{
    public string sceneName;

    private Text text_LoadProgress;
    private AsyncOperation ao;
    private bool isLoad = false;
    private void Awake()
    {
        text_LoadProgress = GetComponent<Text>();
        EventCenter.AddListener(EventDefine.startLoadScene, StartLoad);
        gameObject.SetActive(false);
    }
    private void OnDestroy()
    {
        EventCenter.RemoveListener(EventDefine.startLoadScene, StartLoad);
    }
    private void StartLoad()
    {
        gameObject.SetActive(true);
        StartCoroutine("Load");
    }
    public IEnumerator Load()
    {
        int displayProgress = -1;
        int toProgress = 100;

        while (displayProgress < toProgress)
        {
            ++displayProgress;
            ShowProgress(displayProgress);

            if(!isLoad)
            {
                ao = SceneManager.LoadSceneAsync(sceneName);
                ao.allowSceneActivation = false;
                isLoad = true;
            }

            yield return new WaitForEndOfFrame();
        }

        if(displayProgress == 100)
        {
            ao.allowSceneActivation = true;
            StopCoroutine("Load");
        }
    }
    private void ShowProgress(int progress)
    {
        text_LoadProgress.text = progress.ToString() + "%";
    }
}

点击全文阅读


本文链接:http://m.zhangshiyu.com/post/31042.html

加载  场景  操作  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1