且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Unity SceneManager场景管理Chinar详解API

更新时间:2022-06-19 03:50:43

Unity 场景API详解


本文提供全图文流程,中文翻译。

Chinar 坚持将简单的生活方式,带给世人!

(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)

Chinar —— 心分享、心创新!

助力快速理解 Unity 场景管理的 API 诸多用法

给新手节省宝贵的时间,避免采坑!


Chinar 教程效果:
Unity SceneManager场景管理Chinar详解API


全文高清图片,点击即可放大观看 (很多人竟然不知道)


1

SceneManager —— 场景管理



我们在游戏开发中,经常用到关卡切换、场景切换、加载场景等诸多功能性操作

Unity 为我们提供了场景管理类,可以很方便的对场景进行各类操作

下边我们就来逐一的看一下,API中的函数具体用法

另附—— 官方API链接

其他

Unity SceneManager场景管理Chinar详解API
Unity SceneManager场景管理Chinar详解API


2

API —— API(创建/获取/加载)



直接给大家贴上中文注释,便于初学者学习

其他易出错的函数, Chinar 也用了简单例子做了说明,避免初学者踩坑!

提示:

其中 0 号场景为: SampleScene

其中 1 号场景为: Chinar
Unity SceneManager场景管理Chinar详解API

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;


/// <summary>
/// 场景管理测试类
/// </summary>
public class ChinarSceneManager1 : MonoBehaviour
{
    /// <summary> 
    /// 初始化函数
    /// </summary>
    void Start()
    {
        SceneManager.CreateScene("Chinar");                             //使用给定名称在运行时创建一个空的新场景
        SceneManager.GetActiveScene();                                  //获取当前活动的场景
        SceneManager.GetSceneAt(0);                                     //在SceneManager的已加载场景列表中获取索引处的场景
        SceneManager.GetSceneByBuildIndex(0);                           //从构建Build Setting中索引获取Scene结构
        SceneManager.GetSceneByName("Chinar");                          //搜索给定名称的场景
        SceneManager.GetSceneByPath("Assets/Scenes/SampleScene.unity"); //搜索给定路径的场景
        SceneManager.LoadScene(1);                                      //根据“Build Setting”中索引加载场景
        SceneManager.LoadScene("Chinar");                               //根据“Build Setting”中名称加载场景
        SceneManager.LoadScene(1,        LoadSceneMode.Additive);       //加载场景,加载方式:保留当前场景,附加指定场景
        SceneManager.LoadScene("Chinar", LoadSceneMode.Single);         //加载场景,加载方式:关闭所有当前加载的场景并加载场景
        SceneManager.LoadSceneAsync(1);                                 //根据下标,在后台异步加载场景
        SceneManager.LoadSceneAsync("Chinar");                          //根据名称,在后台异步加载场景
        SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive);         //异步加载,方式:附加
        SceneManager.LoadSceneAsync(1);                                 //异步加载,方式:单一
        SceneManager.UnloadSceneAsync("Chinar");                        //销毁与给定场景关联的所有GameObject,并从SceneManager中移除场景。
    }
}

3

API (Merge) —— 常用API(合并/移动对象/设置活动)



有时我们需要将场景合并

或者将当前场景的游戏对象,移动到其他场景中 / 设置活跃场景

提示:

进行这三类操作,都需要先将目标场景加载后,才可保证函数正确执行

这里为了便于初学者理解,我用了协成加载的方式,来做说明

其中 0 号场景为: SampleScene

其中 1 号场景为: Chinar
Unity SceneManager场景管理Chinar详解API

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;


/// <summary>
/// 场景管理测试类
/// </summary>
public class ChinarSceneManager1 : MonoBehaviour
{
    /// <summary> 
    /// 初始化函数
    /// </summary>
    void Start()
    {
        StartCoroutine(MergeMethodEnumerator());           //合并场景
        StartCoroutine(MoveGameObjectToSceneEnumerator()); //移动游戏对象到目标场景
        StartCoroutine(SetActiveSceneEnumerator());        //设置场景为活动场景
    }


    /// <summary>
    /// 合并场景
    /// 必须要保证:要合并的场景被加载后,才可以正确合并
    /// 如果物体名称相同,并不会合并,相互独立
    /// </summary>
    IEnumerator MergeMethodEnumerator()
    {
        yield return SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive);                           //等待场景加载完毕后,再向下执行
        SceneManager.MergeScenes(SceneManager.GetSceneByBuildIndex(1), SceneManager.GetActiveScene()); //源场景 1,目标场景:当前 —— 将源场景合并到目标场景中
    }


    /// <summary>
    /// 移动游戏对象到新场景
    /// 必须要保证:目标场景被加载后,游戏对象才能被正确移动到目标场景中
    /// 如果物体名称相同,并不会合并,相互独立
    /// </summary>
    IEnumerator MoveGameObjectToSceneEnumerator()
    {
        yield return SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive);                                //等待场景加载完毕后,再向下执行
        SceneManager.MoveGameObjectToScene(GameObject.Find("Cube"), SceneManager.GetSceneByName("Chinar")); //将当前场景中的 Cube,移动到目标场景中
        SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene());                                       //卸载掉当前场景
        //如果要加载单个场景,请确保在要移动到新场景的GameObject上使用DontDestroyOnLoad,否则Unity会在加载新场景时删除它。
    }


    /// <summary>
    /// 设置场景为活动场景
    /// 必须要保证:目标场景被加载后,才可以正确设置活动状态
    /// </summary>
    IEnumerator SetActiveSceneEnumerator()
    {
        yield return SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive); //等待场景加载完毕后,再向下执行
        SceneManager.SetActiveScene(SceneManager.GetSceneAt(1));             //设置场景为活动场景
        //print(SceneManager.GetSceneAt(1).IsValid());
    }
}

4

Scene (Events) —— 场景事件



有时我们需要场景记载/卸载/变更时,进行一系列操作

这时我们需要用事件来完成通知

提示:

其中 0 号场景为: SampleScene

其中 1 号场景为: Chinar
Unity SceneManager场景管理Chinar详解API

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;


/// <summary>
/// 场景管理测试类
/// </summary>
public class ChinarSceneManager1 : MonoBehaviour
{
    /// <summary> 
    /// 初始化函数
    /// </summary>
    void Start()
    {
        SceneManager.activeSceneChanged += SceneManager_activeSceneChanged; //订阅此事件可在活动场景发生更改时收到通知。
        StartCoroutine(SetActiveSceneEnumerator());                         //活动场景切换时,会收到通知,打印输出"活动场景变更了"
        SceneManager.sceneLoaded += SceneManager_sceneLoaded;               //委托 —— 加载场景时收到通知
        SceneManager.LoadSceneAsync(1);                                     //异步加载,加载方式:单一
        SceneManager.sceneUnloaded += SceneManager_sceneUnloaded;           //委托 —— 卸载Scene时收到通知
    }


    /// <summary>
    /// 设置场景为活动场景
    /// 必须要保证:目标场景被加载后,才可以正确设置活动状态
    /// </summary>
    IEnumerator SetActiveSceneEnumerator()
    {
        yield return SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive); //等待场景加载完毕后,再向下执行
        SceneManager.SetActiveScene(SceneManager.GetSceneAt(1));             //设置场景为活动场景
    }


    /// <summary>
    /// 活动场景变动时被调用
    /// </summary>
    private void SceneManager_activeSceneChanged(Scene arg0, Scene arg1)
    {
        print("活动场景变更了");
    }


    /// <summary>
    /// 场景被加载后,被调用
    /// </summary>
    private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
    {
        print("场景被加载了");
    }


    /// <summary>
    /// 场景被卸载时,被调用
    /// </summary>
    private void SceneManager_sceneUnloaded(Scene arg0)
    {
        print("场景被卸载了");
    }
}

5

Scene —— 场景自身的一些属性



Scene 类自身具备一些属性和字段,便于我们对场景的状态进行了解/操作
提示:

其中 0 号场景为: SampleScene

其中 1 号场景为: Chinar
Unity SceneManager场景管理Chinar详解API

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;


/// <summary>
/// 场景管理测试类
/// </summary>
public class ChinarSceneManager1 : MonoBehaviour
{
    /// <summary> 
    /// 初始化函数
    /// </summary>
    void Start()
    {
        print(SceneManager.GetActiveScene().buildIndex);           //返回“Build Setting”中场景的索引。如果场景是通过AssetBundle加载的,则始终返回-1。
        print(SceneManager.GetActiveScene().isDirty);              //如果场景被修改,则返回true。
        print(SceneManager.GetActiveScene().isLoaded);             //如果加载场景,则返回true。
        print(SceneManager.GetActiveScene().name);                 //返回场景的名称。
        print(SceneManager.GetActiveScene().path);                 //返回场景的相对路径。喜欢:“Assets/Scenes/SampleScene.unity”。
        print(SceneManager.GetActiveScene().rootCount);            //返回场景的游戏对象个数
        print(SceneManager.GetActiveScene().GetHashCode());        //返回场景的哈希值
        print(SceneManager.GetActiveScene().GetRootGameObjects()); //返回场景中所有游戏对象,是一个GameObject[] 数组
        foreach (var a in SceneManager.GetActiveScene().GetRootGameObjects())
        {
            print(a.name);
        }
        StartCoroutine(SetActiveSceneEnumerator());  //设置场景为活动场景
        print(SceneManager.GetSceneAt(1).IsValid()); //判断场景是否有效,如果场景未被加载/或是不存在,则场景可能无效
    }


    /// <summary>
    /// 设置场景为活动场景
    /// 必须要保证:目标场景被加载后,才可以正确设置活动状态
    /// </summary>
    IEnumerator SetActiveSceneEnumerator()
    {
        yield return SceneManager.LoadSceneAsync(1, LoadSceneMode.Additive); //等待场景加载完毕后,再向下执行
        SceneManager.SetActiveScene(SceneManager.GetSceneAt(1));             //设置场景为活动场景
    }
}

其他

May Be —— 搞开发,总有一天要做的事!


拥有自己的服务器,无需再找攻略!

Chinar 提供一站式教程,闭眼式创建!

为新手节省宝贵时间,避免采坑!




服务器、建站、备案、网站配置等(服务器相关教程大全)


END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究

对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com

对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址