Unity--异步加载场景

Unity–异步加载场景

异步加载场景其实和异步加载资源是一样的,只是加载的内容比较特殊而已. 也可以将场景视为特殊资源.

1.SceneManager.LoadScene

加载场景的方式,在Unity 中加载场景是通过SceneManager.LoadScene("场景名称"); 来实现加载场景,这和UE4中的OpenLevel也是一样的. 其中SceneManager是untiy中自带的场景管理器,可以用于加载场景,卸载场景等.需要引入using UnityEngine.SceneManagement才能使用

2.同步加载场景

和资源一样,场景默认是同步加载的,也就是直接使用SceneManager.LoadScene("场景名称")来实现同步加载. 如果一个场景中的资源比较多,比如:游戏模型,粒子特效等,那么就会导致加载场景时候卡顿,很久才能加载场景.

需要注意的是,它会立即切换到新场景,这可能导致短暂的冻结或卡顿,特别是在加载较大或资源密集的场景时…为了解决这个问题,我们一般使用异步加载. 减轻主线程的压力.

3.异步加载场景

和异步加载资源一样,场景的异步加载也是有两个过程: 加载中与加载完成.

异步加载的重要性:异步加载(LoadSceneAsync)允许场景在后台加载,这样主线程可以继续处理其他任务,如更新UI、处理玩家输入等。这对于提高用户体验至关重要,特别是在资源密集型游戏中。

仔细分析就是因为资源过大,内容过多导致加载中的时间过长,我们一般的设计方式就是进度条,加载完毕一段内容,进度条走了20%或者其他.直到加载完毕才走到100%,当然这个进度条有可能是假的.

在Unity中异步加载场景的写法如下:使用异步加载关键 + 加载完毕的回调函数

/// <summary>
/// 普通异步加载场景 + 调用回调函数
/// </summary>
/// <param name="scenenName">场景名称</param>
void LoadSceneAsychonized(string sceneName)
{// 加载场景AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);operation.completed += LoadSceneCompleted;
}

其中SceneManager.LoadSceneAsync(sceneName);sceneName就是我们要加载的场景名称. 返回值是一个异步加载操作的对象AsyncOperation .和上面将的一样,加载场景有两个状态:加载中与加载完毕.

AsyncOperation对象:其中AsyncOperation operation就是记录了场景是否加载完毕isDown,没有加载完毕就是在加载中. 当场景处于加载中,我们就能获取场景的加载进度progress, 优先级priority以及当场景准备好了就激活场景allowSceneActivation. 还有加载完毕的回调函数completed.
AsyncOperation对象:这是异步加载的核心。它提供了加载进度(progress)、是否完成(isDone)等重要信息。通过这些属性,可以创建进度条或执行其他加载相关的逻辑。

属性/方法含义
isDown是否加载完成
progress场景的加载进度0-1的值,Unity很多时候是0.9,这个值准确
priority优先级
allowSceneActivation收否在场景准备好了就激活场景
completed加载完毕的回到函数

以下是AsyncOperationC#中的代码

namespace UnityEngine
{//// 摘要://     Asynchronous operation coroutine.[NativeHeader("Runtime/Export/Scripting/AsyncOperation.bindings.h")][NativeHeader("Runtime/Misc/AsyncOperation.h")][RequiredByNativeCode]public class AsyncOperation : YieldInstruction{public AsyncOperation();~AsyncOperation();// 摘要:Has the operation finished? (Read Only)public bool isDone { get; }// 摘要: What's the operation's progress. (Read Only)public float progress { get; }// 摘要: Priority lets you tweak in which order async operation calls will be performed.public int priority { get; set; }// 摘要:Allow Scenes to be activated as soon as it is ready.public bool allowSceneActivation { get; set; }public event Action<AsyncOperation> completed;}
}

注意,场景加载完毕后我们需要用一个函数来做一些其他内容, 比如:设置场景初始化[这里需要说明的是加载场景不等于初始化场景],还可以设置游戏状态,UI的显示隐藏等.

 private void LoadSceneCompleted(AsyncOperation operation){// 场景加载完成后执行的代码Debug.Log("Scene loaded successfully");// ... ...// 在这里可以进行场景初始化,例如查找和初始化游戏对象,设置游戏状态等}

4.使用协程的方式异步加载场景

利用AsyncOperation operation的isDone数显来判断是否加载完毕, 如果没有加载完毕,就不可以做一些其他事情,并使用yield return来等待一段时间,然后继续判断是否加载完毕,代码如下:

/// <summary>/// 自定义协程加载场景/// </summary>/// <param name="operation"></param>/// <returns></returns>IEnumerator LoadWaitScene(AsyncOperation operation){// 获得加载进度while(! operation.isDone){Debug.Log("加载中...\t进度: " + operation.progress);if (operation.progress >= 0.9f){// 激活场景 Allow Scenes to be activated as soon as it is ready.operation.allowSceneActivation = true;}// 自己做个假的进度条yield return null;}}

我们也可以直接在协程里使用yield return operaiton来判断是否记加载完毕, 需要注意的是,一旦获得了加载操作的对象那么yeild return xxx后的代码就无法执行.因为场景加载好了,切换到了新的场景,旧的场景中的内容会被销毁,也包括我们挂载的脚本

IEnumerator LoadScene(string sceneName){DontDestroyOnLoad(this.gameObject);AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);Debug.Log("加载中...");yield return operation;// 后面的内容无法打印,因为场景被加载完毕,当前场景上游戏物体,脚本被移除Debug.Log("场景加载完毕后打印数据");// 要想场景加载完毕后也可以继续执行yield return 后的代码,需要使用 DontDestroyOnLoad 来保存数据// 注意: DontDestroyOnLoad 这个代码要放在异步加载场景之前的任意位置,可以是在协程前,可以是在开启异步加载场景协程前.Debug.Log("加载场景时不销毁对象");// 场景加载结束,但不急着显示场景// 场景加载结束, 进度条更新一段// 接着加载场景中的其他信息// 加载怪物-怪物加载完毕进度条更新一段// 动态加载 场景模型// 这时候就认为加载完毕,进度条设置100%, 隐藏进度条}

5.DontDestroyOnLoad

如何保持旧场景指定游戏对象/脚本/组件不被销毁? 这时候需要使用DontDestroyOnLoad这个方法来让我们指定的兑现不销毁.下面的代码表示加载场景后销毁气其他资源 ,不销毁当前脚本挂载的游戏物体,自然,当前脚本就不会被销毁了. DontDestroyOnLoad()这是一个重要的方法,用于在场景切换时保留特定的游戏对象。这在某些情况下非常有用,比如保留音效管理器或全局配置对象

 DontDestroyOnLoad(this.gameObject);

6.自己写一个场景管理器

为了避免每一次加载场景的时候都要自己手动写鞋厂或者回调函数,我们可以将这样的方案构成一个类, 值需要传入一个场景名称和一个加载完毕的函数名称就行. 该类最好可以在任意地方使用,因此,我们可以将场景管理类写成一个单例. 这和Unity自带的ScenManager是一个意思,只是自己有了自己自定义的部分. 代码如下:

public class MySceneManager
{private static MySceneManager instance = new MySceneManager();private MySceneManager() { }public static MySceneManager Instance => instance;/// <summary>/// 外部调用异步加载场景的方法/// </summary>/// <param name="sceneName"> 场景名 </param>public void LoadScene(string sceneName, UnityAction action){AsyncOperation ao = SceneManager.LoadSceneAsync(sceneName);ao.completed += (a) =>{action(); // 调用外部的函数};}
}

测试脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TestMySceneManager : MonoBehaviour
{    void Update(){if(Input.GetKeyDown(KeyCode.A)){MySceneManager.Instance.LoadScene("测试场景", loadCompleteAction);}}private void loadCompleteAction(){Debug.Log("场景加载完毕");}
}

7.测试和优化:

在实现异步加载时,测试不同的场景大小和资源负载非常重要。这有助于发现潜在的性能瓶颈并优化加载过程。

8.资源打包和加载策略:

除了异步加载,合理的资源打包和加载策略也对性能有显著影响。考虑使用AssetBundlesAddressables来优化资源的加载和管理。

9.用户体验:

在加载过程中,提供清晰的反馈(如进度条、加载动画)对于提升用户体验至关重要。这可以让玩家知道游戏正在加载,而不是卡顿或无响应。

最后,确保在实现异步加载时,对Unity的版本和平台特性有一定的了解,因为它们可能会影响异步加载的行为和性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/40983.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在Java中实现批量数据处理

如何在Java中实现批量数据处理 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. 引言 在大数据时代&#xff0c;处理大量数据是许多应用程序中必不可少的需…

自动化立体仓库出入库能力及堆垛机节拍

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》人俱乐部 完整版文件和更多学习资料&#xff0c;请球友到知识星球【智能仓储物流技术研习社】自行下载 自动化立体仓库的出入库能力、堆垛机节拍以…

安全协议:SSL/TLS与Java实现

在当今的互联网环境中&#xff0c;数据安全至关重要。SSL&#xff08;Secure Sockets Layer&#xff09;和其继任者TLS&#xff08;Transport Layer Security&#xff09;是确保数据在网络中安全传输的关键技术。本文将详细介绍SSL/TLS协议的工作原理&#xff0c;并通过Java代码…

掌握电路交换与分组交换:计算机网络的核心技术

计算机网络是现代信息社会的基石&#xff0c;而交换技术是实现网络通信的核心。本文将详细介绍两种典型的交换方式&#xff1a;电路交换和分组交换&#xff0c;帮助基础小白快速掌握这两种技术的基本概念和区别。 什么是电路交换&#xff1f; 电路交换&#xff08;Circuit Swi…

Java中的服务化架构设计与实现

Java中的服务化架构设计与实现 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. 引言 随着软件系统规模的不断扩大和业务需求的增加&#xff0c;传统的单体…

CentOS7开启sshd失败解决方法

Could not load host key: /etc/ssh/ssh_host_rsa_key Could not load host key: /etc/ssh/ssh_host_ecdsa_key Could not load host key: /etc/ssh/ssh_host_ed25519_key sshd: no hostkeys available – exiting. 1、检查主机密钥文件是否存在 ls -l /etc/ssh/ssh_host_*2、…

Centos系统迁移

目前&#xff0c;CentOS 全系列版本已经于l六月底正式停止维护&#xff0c;这意味着 CentOS 时代彻底终结&#xff0c;也意味着部署在 CentOS 7 上的业务系统将面临前所未有的安全挑战。 本文推荐由红帽衍生出来的且可以做到真正无缝替代的linux版本Open Euler 注&#xff1a…

【前端】面试八股文——输入URL到页面展示的过程

【前端】面试八股文——输入URL到页面展示的过程 1. DNS解析 当用户在浏览器中输入URL并按下回车时&#xff0c;首先需要将域名转换为IP地址&#xff0c;这个过程称为DNS&#xff08;域名系统&#xff09;解析。具体步骤如下&#xff1a; 浏览器缓存&#xff1a;浏览器首先检…

科普文:Linux服务器性能调优概叙

概叙 Java web应用性能分析之服务端慢和优化概叙_cpu飙高java-CSDN博客 Java web应用性能分析之【CPU飙升分析概述】_web页面性能分析cpu占满是因为死循环,还是循环过多-CSDN博客 在我们的软件服务中&#xff0c;软件部署的服务器&#xff0c;一般都是linux服务器&#xff0c…

ubuntu20.04安装lio-sam

1、boost版本 boost版本查看&#xff1a;cat /usr/include/boost/version.hpp | grep "BOOST_LIB_VERSION" boost版本为1.78&#xff0c;为1.71时编译报错&#xff0c;报错内容为&#xff1a; error: missing binary operator before token "(" 60 |…

面向txt/json/xlsx/csv的文件读写及编码问题

专栏介绍 1.专栏面向零基础或基础较差的机器学习入门的读者朋友,旨在利用实际代码案例和通俗化文字说明,使读者朋友快速上手机器学习及其相关知识体系。 2.专栏内容上包括数据采集、数据读写、数据预处理、分类\回归\聚类算法、可视化等技术。 3.需要强调的是,专栏仅介绍主…

每日一道算法题 彩灯装饰记录 I

题目 LCR 149. 彩灯装饰记录 I - 力扣&#xff08;LeetCode&#xff09; Python # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right …

Redis五种数据结构及其常用使用场景

引言 Redis 是一种高性能的键值对数据库&#xff0c;支持多种数据类型&#xff0c;每种类型都有其独特的使用场景和优势。在本篇博客中&#xff0c;我们将深入探讨 Redis 的五种主要数据结构&#xff1a;字符串&#xff08;String&#xff09;、哈希&#xff08;Hash&#xff…

Java中的RPC远程过程调用技术详解

Java中的RPC远程过程调用技术详解 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在分布式系统中&#xff0c;RPC&#xff08;Remote Procedure Call&#xf…

rtsp地址 + 测试网站 + java(免环境、免插件、零编码转换http播放)

目录 1、创建rtsp网站 2、测试rtsp网站 3、Java实现rtsp播放 ①maven添加依赖 ②访问http地址即可展示视频内容 1、创建rtsp网站 填写邮箱即可获得两个可用的rtsp网站&#xff08;每月可免费用2G&#xff09;&#xff1a; https://rtsp.stream/ 2、测试rtsp网站 测试网络…

基于SpringBoot的地方废物回收机构管理系统

本系统主要包括管理员和员工两个角色组成&#xff1b;主要包括&#xff1a;首页、个人中心、员工管理、员工请假管理、销假申请管理、工作日志管理、员工工资管理、员工任务管理、任务汇报管理、设备信息管理、设备借用管理、设备归还管理、设备保修管理、维修入库管理、员工打…

Python酷库之旅-第三方库Pandas(002)

目录 一、用法精讲 1、pandas.read_pickle函数 1-1、语法 1-2、参数 1-3、功能 1-4、返回值 1-5、说明 1-6、用法 1-6-1、代码示例 1-6-2、结果输出 2、pandas.DataFrame.to_pickle方法 2-1、语法 2-2、参数 2-3、功能 2-4、返回值 2-5、说明 2-5-1、文件路径…

数据结构(3.8)——栈的应用

栈在括号匹配中的应用 流程图 代码 #include <stdio.h> #include <stdlib.h> #define MaxSize 10typedef struct {char data[MaxSize];int top; } SqStack;// 初始化栈 void InitStack(SqStack* S) {S->top -1; // 初始化栈顶指针 }// 判空 bool StackEmpty(…

Apache Hadoop完全分布式集群搭建指南

Hadoop发行版本较多,Cloudera版本(Cloudera’s Distribution Including Apache Hadoop,简称CDH)收费版本通常用于生产环境,这里用开源免费的Apache Hadoop原始版本。 下载:Apache Hadoop 版本下载:Index of /hadoop/common Hadoop基础知识可查看本专栏其它篇章:Apac…

《米小圈日记魔法》边看边学,轻松掌握写日记的魔法!

在当今充满数字化娱乐和信息快速变迁的时代&#xff0c;如何创新引导孩子们学习&#xff0c;特别是如何培养他们的写作能力&#xff0c;一直是家长和教育者们关注的焦点。今天就向大家推荐一部寓教于乐的动画片《米小圈日记魔法》&#xff0c;该系列动画通过其独特的故事情节和…