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.pswp.cn/diannao/40983.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/40983.shtml
英文地址,請注明出處:http://en.pswp.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;該系列動畫通過其獨特的故事情節和…