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()
    {
        
    }
}
相关推荐
驰愿9 小时前
ET EntityRef EntityWeakRef 类分析
unity·et
敲代码的 蜡笔小新17 小时前
【行为型之中介者模式】游戏开发实战——Unity复杂系统协调与通信架构的核心秘诀
unity·设计模式·c#·中介者模式
敲代码的 蜡笔小新19 小时前
【行为型之解释器模式】游戏开发实战——Unity动态公式解析与脚本系统的架构奥秘
unity·设计模式·游戏引擎·解释器模式
敲代码的 蜡笔小新1 天前
【行为型之观察者模式】游戏开发实战——Unity事件驱动架构的核心实现策略
观察者模式·unity·设计模式·c#
向宇it1 天前
【unity游戏开发——编辑器扩展】使用EditorGUI的EditorGUILayout绘制工具类在自定义编辑器窗口绘制各种UI控件
开发语言·ui·unity·c#·编辑器·游戏引擎
qq_205279051 天前
unity 鼠标更换指定图标
unity·游戏引擎
FAREWELL000751 天前
Unity基础学习(九)输入系统全解析:鼠标、键盘与轴控制
学习·unity·c#·游戏引擎
敲代码的 蜡笔小新1 天前
【行为型之策略模式】游戏开发实战——Unity灵活算法架构的核心实现策略
unity·设计模式·c#·策略模式
Flamesky2 天前
Unity编辑器重新编译代码
unity·重新编译
qq_5982117573 天前
Unity.UGUI DrawCall合批笔记
笔记·unity·游戏引擎