obsidian/笔记文件/2.笔记/Scene切换场景的笔记.md
2025-03-26 00:02:56 +08:00

13 KiB
Raw Permalink Blame History

#unity/日常积累

用脚本实例化的游戏对象都会生成在活动场景中。

哪个场景是活动场景,则当前的天空盒就会使用该场景的天空盒。

只能有一个场景是活动场景。

在Hierarchy右击一个场景点击“Set Active Scene”可以手动把这个场景设置为活动场景。也可以使用SceneManager.SetActiveScene方法把一个加载了的场景设置为活动场景。

首先把要跳转的场景都拖进File——Build Settings中

必须先引入命名空间using UnityEngine.SceneManagement;

SceneManager.sceneCount 当前已经加载的场景的数量。

SceneManager.sceneCountInBuildSettings 已经添加到Build Settings窗口中的场景的数量。 如果在编辑器模式下则进入播放模式之前已经打开的场景也会包含在内如果它没有手动拖到Build Settings窗口则它在Build Settings窗口中也是有索引的只是我们看不到这个索引比可以看得到的最大1。

SceneManager.CreateScene(int 场景名) 创建一个空场景,这个空场景会叠加到当前场景。 如果创建的场景名重复,则会报错。 场景名可以在Hierarchy窗口看到。 如果要在编辑时创建场景例如在创建编辑器脚本或工具时需要创建场景则应使用EditorSceneManager.NewScene

SceneManager.CreateScene(string 场景名,CreateSceneParameters 创建场景的各种参数) 创建一个空场景,这个场景会叠加到当前场景。 如果创建的场景名重复,则会报错。 场景名可以在Hierarchy窗口看到。 如果要在编辑时创建场景例如在创建编辑器脚本或工具时需要创建场景则应使用EditorSceneManager.NewScene

SceneManager.GetActiveScene() 返回Scene型对象表示当前场景的信息。

SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); 使用同步的方式,重新切换到当前场景。

SceneManager.GetActiveScene().buildIndex+1表示下一个场景在Build Settings窗口中的索引。

SceneManager.GetActiveScene().name string型。表示当前场景的名字。可以配合SceneManager.LoadScene使用重新加载当前场景

SceneManager.GetSceneAt(int 索引) 在当前已加载的场景的列表中,返回指定索引的场景的信息。 索引必须大于等于0最小为0。如果为负数或者索引越界则会报错。

SceneManager.GetSceneByBuildIndex(int 场景在Build Settings窗口中的索引) 根据传入的索引返回Build Settings中的场景的信息。 该场景必须在Build Settings窗口中且当前已经加载这样才会返回它的信息。否则会返回一个无效的Scene型对象。 索引必须大于等于0最小为0。如果为负数或者索引越界则会报错。

SceneManager.GetSceneByName(string 场景名) 在当前已经加载的场景中,查找指定场景名的场景。 如果找到了则返回一个Scene对象表示这个场景的信息。如果找不到则返回一个无效的Scene对象。 场景名可以是Build Settings窗口中所示名称的最后一部分在这种情况下将返回第一个匹配的场景信息。 场景名也可以是Build Settings窗口中显示的路径在这种情况下将返回精确匹配到的场景信息。 场景名不区分大小写。 场景名一定不得包含.unity扩展名。

SceneManager.GetSceneByPath(string 场景的路径) 在当前已经加载的场景中,查找具有指定资源路径的场景。 如果找到了则返回一个Scene对象表示这个场景的信息。如果找不到则返回一个无效的Scene对象。 场景的路径应是项目文件夹的相对路径例如“Assets/MyScenes/MyScene.unity”

SceneManager.LoadScene(int 场景在Build Settings窗口中的索引,LoadSceneMode 加载场景的模式); 同步加载指定索引的场景。 第一个参数可以使用string型这样就会根据场景名或者场景路径来加载指定的场景。此时这个名字的场景要么提前放到Build Settings窗口中要么之前已经用了AssetBundle加载这样一来这个方法才会有效。如果都没有则会报错。注意场景名不包含.unity的后缀。还有场景名不要重名如果重名则会加载匹配到的第一个场景。可以使用场景路径例如Assets/AssetBundleAssets/Scenes/TestScenes/Scene1.unity 如果第二个参数使用LoadSceneMode.Single则加载完毕后会自动切换到该场景。原来场景会被卸载。默认就是使用这个。 如果第二个参数使用LoadSceneMode.Additive则加载完毕后该场景会叠加到原来的场景中。原来的场景不会被卸载且活动场景依然是原来的场景。 使用此方法加载场景不会立即加载而是会在下一帧才开始加载。而且由于此方法是同步的所以可能会出现卡顿现象建议使用异步加载的LoadSceneAsync方法。

SceneManager.LoadSceneAsync(int 场景在Build Settings窗口中的索引,LoadSceneMode 加载场景的模式); 异步加载指定索引的场景。 第一个参数可以使用string型这样就会根据场景名或场景路径来加载指定的场景。此时这个名字的场景要么提前放到Build Settings窗口中要么之前已经用了AssetBundle加载这样一来这个方法才会有效。如果都没有则会报错。注意场景名不包含.unity的后缀。还有场景名不要重名如果重名则会加载匹配到的第一个场景。可以使用场景路径例如Assets/AssetBundleAssets/Scenes/TestScenes/Scene1.unity 如果第二个参数使用LoadSceneMode.Single则加载完毕后可以切换到该场景那么原来场景会被卸载。默认就是使用这个。 如果第二个参数使用LoadSceneMode.Additive则加载完毕后该场景可以叠加到原来的场景中。原来的场景不会被卸载且活动场景依然是原来的场景。 使用此方法加载场景不会卡住游戏,往往配合场景中的进度条来使用,可以一边加载场景,一边控制进度条的推进。 这个方法的返回值类型的是AsyncOperation类型可以根据这个类型的对象来判断异步加载是否完成。具体可以参考AsyncOperation类。

SceneManager.MergeScenes(Scene 场景1,Scene 场景2) 将场景1的所有游戏对象全部转移到场景2且场景1会被卸载掉。 一般在加载场景时使用了LoadSceneMode.Additive来加载才可能会使用这个方法。 场景1和场景2都必须是已加载的场景。 如果原来的场景1是活动场景这样它被卸载掉之后Hierarchy窗口中最上面的第一个场景就会变成活动场景。 如果原来的场景1不是活动场景这样它被卸载掉之后活动场景不变。

SceneManager.MoveGameObjectToScene(GameObject 要移动的游戏对象,Scene 移动到场景) 将一个游戏对象从它所在的场景移动到目标场景中。 一般在加载场景时使用了LoadSceneMode.Additive来加载才可能会使用这个方法。 要移动到的场景必须是已加载的场景。 如果要移动的游戏对象为null则本方法无效。 如果移动到的场景没有加载完成,或者是无效的场景,则会报错。

SceneManager.SetActiveScene(Scene 场景名) 将指定的场景设置为活动场景。

SceneManager.UnloadSceneAsync(int 场景在Build Settings窗口中的索引) SceneManager.UnloadSceneAsync(string 场景名或场景路径) SceneManager.UnloadSceneAsync(Scene 场景对象) SceneManager.UnloadSceneAsync(int 场景在Build Settings窗口中的索引,UnloadSceneOptions 卸载场景的选项) SceneManager.UnloadSceneAsync(string 场景名或场景路径,UnloadSceneOptions 卸载场景的选项) SceneManager.UnloadSceneAsync(Scene 场景对象,UnloadSceneOptions 卸载场景的选项) 销毁指定的场景和这个场景中的所有游戏对象。 本方法只对加载时用了LoadSceneMode.Additive所加载的场景有效。如果当前游戏中只有一个场景则本方法无效控制台会报黄色的警告。 本方法不会卸载内存中的场景资源如果要释放资源应在调用这个方法后再调用Resources.UnloadUnusedAssets方法 返回值的类型是AsyncOperation类型可以根据这个对象来确定异步操作是否完成。

SceneManager.activeSceneChanged UnityAction<Scene,Scene>型的事件。 当活动场景发生变化时,会执行一次这个事件。 第一个参数表示原来的活动场景,第二个参数表示后来的活动场景。

SceneManager.sceneLoaded UnityAction<Scene,LoadSceneMode>型的事件。 每当有新的场景被加载时,会执行一次这个事件。 第一个参数表示加载的新的场景,第二个参数表示这个场景加载的模式。

SceneManager.sceneUnloaded UnityAction型的事件。 每当有场景被卸载时,会执行一次这个事件。 参数表示卸载的场景对象。

Scene类的对象用来存储场景的信息。

Scene型对象.buildIndex 返回int型表示该场景在Build Settings窗口中的索引。 如果该场景是无效的场景,则这个变量的值为-1 如果该场景是通过AssetBundle加载的场景则这个变量的值也为-1

Scene型对象.isDirty 返回bool型表示该场景是否被修改了。 当我们在编辑器模式下修改了某一个场景但是没有保存则此时这个变量的值为true。一旦该场景保存了则这个变量的值为false

Scene型对象.isLoaded 如果该场景已经加载了则返回true。如果该场景还没有加载或没有加载完成则返回false

Scene型对象.name 返回string型表示该场景的名字结尾不包含后缀.unity 也就是它在Project窗口中的名字。 注意:该场景必须已经加载了,这个变量才能正确返回它的场景名。如果该场景还没有加载或没有加载完成,则返回的值是"Null"

Scene型对象.path 返回string型表示该场景的路径结尾包含后缀.unity 例如: Assets/AssetBundleAssets/Scenes/TestScenes/Test.unity

Scene型对象.rootCount 返回int型表示该场景中所有根游戏对象身上的Transform组件的总数。

Scene型对象.GetRootGameObjects 返回GameObject[]型,表示该场景中所有根游戏对象。 隐藏的根游戏对象也会包含在其中但是DontDestoryOnLoad的根游戏对象不会包含在其中。

Scene型对象.IsValid 如果一个场景是存在的它就是有效场景这个变量的值就为true 如果一个场景是不存在的它就是无效场景这个变量的值就为false 注意从EditorSceneManager.OpenScene返回的场景的 IsValid 的值是 false

两个场景对象之间可以使用运算符!= 如果这两个场景不同则返回true否则返回false

两个场景对象之间可以使用运算符== 如果这两个场景相同则返回true否则返回false

AsyncOperation相关的代码应写在一个协同程序中。

AsyncOperation 对象名=SceneManager.LoadSceneAsync(string 场景名) 开启异步加载场景并把异步加载的信息存储在AsyncOperation型对象中。

AsyncOperation型对象.allowSceneActivation 返回bool型表示是否允许在场景加载完毕后立即激活该场景。 值为true表示一旦该场景异步加载完毕则会立即激活该场景。 值为false表示即使加载场景完毕也不会激活该场景直到用代码再次把这个变量的值改为true才会激活该场景。

AsyncOperation型对象.progress 返回float型范围是0-1。表示异步加载的进度开始是0完成时是1 注意当AsyncOperation型变量.allowSceneActivation的值为false这个参数的值最多会卡在0.9直到AsyncOperation型变量.allowSceneActivation的值变为true这个参数的值才会变为1

AsyncOperation型对象.isDone 返回bool型。表示该异步加载是否完成。如果完成则值为true如果未完成则值为false。 当AsyncOperation型对象.progress的值为1时此时这个变量的值才为true但这样就会激活新的新场景一般很难观测到AsyncOperation型对象.isDone是true

AsyncOperation型对象.priority 返回int型用于设置异步操作的优先级。 当有多个异步操作排队时,将优先执行更高优先级的异步操作。但如果异步操作在后台线程上启动, 则更改优先级没有任何效果。

AsyncOperation.completed 这个是一个有一个AsyncOperation型参数的Action事件。该AsyncOperation型参数存储了本次异步加载的信息。 当异步加载完成也就是AsyncOperation型对象.isDone的值为true时会执行一次这个事件。