unity学习23:场景scene相关,场景信息,场景跳转

目录

[1 默认场景和Assets里的场景](#1 默认场景和Assets里的场景)

[1.1 scene的作用](#1.1 scene的作用)

[1.2 scene作为project的入口](#1.2 scene作为project的入口)

[1.3 默认场景](#1.3 默认场景)

[2 场景scene相关](#2 场景scene相关)

[2.1 创建scene](#2.1 创建scene)

[2.2 切换场景](#2.2 切换场景)

[2.3 build中的场景,在构建中包含的场景](#2.3 build中的场景,在构建中包含的场景)

(否则会认为是失效的Scene)

[2.4 Scenes in Build 的 场景索引](#2.4 Scenes in Build 的 场景索引)

[3 场景相关信息](#3 场景相关信息)

[3.1 场景名称 scene.name](#3.1 场景名称 scene.name)

[3.2 场景索引 scene.buildIndex](#3.2 场景索引 scene.buildIndex)

[3.3 场景路径 scene.path](#3.3 场景路径 scene.path)

[3.4 scene.GetRootGameObjects();](#3.4 scene.GetRootGameObjects();)

[4 场景相关测试](#4 场景相关测试)

[4.1 获取当前场景 SceneManager.GetActiveScene()](#4.1 获取当前场景 SceneManager.GetActiveScene())

[4.2 跳转场景 SceneManager.LoadScene();](#4.2 跳转场景 SceneManager.LoadScene();)

[4.2.1 具体参数](#4.2.1 具体参数)

[4.3 场景是否已经加载 scene.isLoaded](#4.3 场景是否已经加载 scene.isLoaded)

[5 测试代码](#5 测试代码)

[5.1 因为用到场景管理SceneManagement](#5.1 因为用到场景管理SceneManagement)

[需要额外导入UnityEngine 和 UnityEngine.SceneManagement;](#需要额外导入UnityEngine 和 UnityEngine.SceneManagement;)

[5.2 第1次测试代码和结果(有错误)](#5.2 第1次测试代码和结果(有错误))

[5.2.1 其他都OK,但是地图生效了,但是读到的信息还是上一张地图的](#5.2.1 其他都OK,但是地图生效了,但是读到的信息还是上一张地图的)

[5.2.2 原因1](#5.2.2 原因1)

[5.2.3 原因2](#5.2.3 原因2)

[5.3 正确代码](#5.3 正确代码)


1 默认场景和Assets里的场景

1.1 scene的作用

  • 游戏里的资源组织
  • unity里的资源组织 / 或者说 层级关系
  • scene1 → gameobjects → componenets
  • scene2 → gameobjects → componenets

1.2 scene作为project的入口

  • unity的游戏工程,一般需要通过scene才能进入
  • Hierarchy(层级窗口) 里一般看到的是当前场景
  • project (工程窗口)里可以看到,project下的Assets里,有一个Scenes文件夹,里面存放着project下的所有场景。

1.3 默认场景

  • 游戏里的默认场景是 SampleScene
  • 一般新建工程都会默认进入这个场景SampleScene
  • 同时,你也可以在 Assets\ Scenes 里找到SampleScene这个场景

2 场景scene相关

2.1 创建scene

  • 在project 里创建,选择地图即可。

2.2 切换场景

  • 双击场景,即可在场景之间切换

2.3 build中的场景,在构建中包含的场景

(否则会认为是失效的Scene)

  • 选择 File / build Settings / Scenes in Build
  • 把新建的场景拖入到 Scenes in Build来

2.4 Scenes in Build 的 场景索引

  • Scenes in Build 的场景索引
  • 后面显示的,0,1,2 就是索引

3 场景相关信息

3.1 场景名称 scene.name

3.2 场景索引 scene.buildIndex

  • //场景索引
  • scene.buildIndex

3.3 场景路径 scene.path

  • //场景路径
  • scene.path

3.4 scene.GetRootGameObjects();

  • scene.GetRootGameObjects()
  • 获得场景 scene下面的所有gb
  • scene.GetRootGameObjects().Length
  • 获得场景 scene下面的所有gb的数量,就是长度

4 场景相关测试

4.1 获取当前场景 SceneManager.GetActiveScene()

  • //获取当前场景
  • SceneManager.GetActiveScene()
  • SceneManager.GetActiveScene() 返回值:会返回一个场景
  • Scene scene=SceneManager.GetActiveScene();

4.2 跳转场景 SceneManager.LoadScene();

  • //跳转场景,可以使用 场景名,或者场景索引
  • SceneManager.LoadScene(2);
  • SceneManager.LoadScene("Scene2");

4.2.1 具体参数

只加载1个,替换之前的Scene

  • SceneManager.LoadScene("Scene2") 默认方式是 LoadSceneMode.Single
  • SceneManager.LoadScene("Scene2",LoadSceneMode.Single)

新的场景加载,老的也在,相当于同时都加载生效

  • SceneManager.LoadScene("Scene2",LoadSceneMode.Additive)

4.3 场景是否已经加载 scene.isLoaded

  • //场景是否已经加载
  • Debug.Log(scene.isLoaded);
  • 返回 T/ F

5 测试代码

5.1 因为用到场景管理SceneManagement

需要额外导入UnityEngine 和 UnityEngine.SceneManagement;

using UnityEngine;

using UnityEngine.SceneManagement;

5.2 第1次测试代码和结果(有错误)

5.2.1 其他都OK,但是地图生效了,但是读到的信息还是上一张地图的

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneTest : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        ///先查看当前Scene
        //获取当前场景
        Scene scene1=SceneManager.GetActiveScene();

        //场景名称
        Debug.Log(scene1.name);

         //场景路径
        Debug.Log(scene1.path);      
    
        //场景索引
        Debug.Log(scene1.buildIndex);   
        GameObject[] gb1=scene1.GetRootGameObjects();
        Debug.Log(gb1.Length);

        //跳转场景
        //SceneManager.LoadScene(2);
        SceneManager.LoadScene("Scene2");

        //获取当前场景
        //新定义1个scene2  Scene scene2=
        Scene scene2=SceneManager.GetActiveScene();

         //场景是否已经加载
        Debug.Log(scene2.isLoaded); 

        ///再次查看当前Scene
        //场景名称
        Debug.Log(scene2.name);

         //场景路径
        Debug.Log(scene2.path);      
    
        //场景索引
        Debug.Log(scene2.buildIndex);   
        GameObject[] gb2=scene2.GetRootGameObjects();
        Debug.Log(gb2.Length);

    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

5.2.2 原因1

  • 场景已经从 Scene1 切换到Scene2 了
  • 但是日志里取到的还是 Scene1的内容,这是为什么?
  • 因为SceneManager.LoadScene方法默认是异步的,新加载的地图可能还没有加载好,而马上去读取信息读取的就还是上一张地图的信息
  • 需要等待新地图加载完成后,就可以了

在Unity中,SceneManager.LoadScene方法默认是异步的,这意味着场景的加载和激活是分开的两个步骤。

当你调用SceneManager.LoadScene("Scene2")时,场景开始加载,但并不会立即激活。

如果代码继续执行,可能会在场景完全加载之前就获取场景信息,这时获取的仍然是上一个场景的信息。

5.2.3 原因2

有可能是场景加载模式问题

  • 在 Unity 里,SceneManager.LoadScene 有两种加载模式:LoadSceneMode.Single(默认)和 LoadSceneMode.Additive。
  • 若采用 LoadSceneMode.Additive 模式加载场景,新场景会叠加到当前场景之上,上一个场景的对象不会被卸载,这就可能致使获取到上一个场景的信息。
  • LoadSceneMode.Additive
  • SceneManager.LoadScene(2, LoadSceneMode.Additive); 这样会导致2个场景都加载,读取时会读到上一个场景的信息
  • 确保使用默认的 LoadSceneMode.Single 模式加载场景,此模式会卸载当前场景并加载新场景。
  • 比如 SceneManager.LoadScene(2);

5.3 正确代码

  • 等待新地图加载后,再读取新地图信息就OK了
  • 如果读取太早,新Scene还没加载进来,读的还是老的Scene的信息
cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneTest : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        ///先查看当前Scene
        //获取当前场景
        Scene scene1=SceneManager.GetActiveScene();

        //场景名称
        Debug.Log(scene1.name);

         //场景路径
        Debug.Log(scene1.path);      
    
        //场景索引
        Debug.Log(scene1.buildIndex);   
        GameObject[] gb1=scene1.GetRootGameObjects();
        Debug.Log(gb1.Length);

        //跳转场景
        //SceneManager.LoadScene(2);
        //SceneManager.LoadScene("Scene2");

        //调用异步的Start1
        Start1();

    }

        async void Start1()
        {
            AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(2);
            // 等待场景加载完成
            while (!asyncLoad.isDone)
            {
                await System.Threading.Tasks.Task.Yield();
            }
            // 场景加载完成后获取信息
            Debug.Log(SceneManager.GetActiveScene().name);

            //获取当前场景
            //新定义1个scene2  Scene scene2=
            Scene scene2=SceneManager.GetActiveScene();

            //场景是否已经加载, 但是可能还没有激活新的Scene
            Debug.Log(scene2.isLoaded); 

            ///再次查看当前Scene
            //场景名称
            Debug.Log(scene2.name);

            //场景路径
            Debug.Log(scene2.path);      
        
            //场景索引
            Debug.Log(scene2.buildIndex);   
            GameObject[] gb2=scene2.GetRootGameObjects();
            Debug.Log(gb2.Length);

        }

    // Update is called once per frame
    void Update()
    {
        
    }
}
相关推荐
星夜泊客14 分钟前
C# 基础:为什么类可以在静态方法中创建自己的实例?
开发语言·经验分享·笔记·unity·c#·游戏引擎
dzj20211 小时前
PointerEnter、PointerExit、PointerDown、PointerUp——鼠标点击物体,则开始旋转,鼠标离开或者松开物体,则停止旋转
unity·pointerdown·pointerup
心前阳光2 小时前
Unity 模拟父子关系
android·unity·游戏引擎
在路上看风景5 小时前
26. Mipmap
unity
咸鱼永不翻身7 小时前
Unity视频资源压缩详解
unity·游戏引擎·音视频
在路上看风景7 小时前
4.2 OverDraw
unity
在路上看风景8 小时前
1.10 CDN缓存
unity
ellis197017 小时前
Unity插件SafeArea Helper适配异形屏详解
unity
nnsix18 小时前
Unity Physics.Raycast的 QueryTriggerInteraction枚举作用
unity·游戏引擎
地狱为王19 小时前
Cesium for Unity叠加行政区划线
unity·gis·cesium