我可以在Unity编辑器中以编程方式加载场景吗?

时间:2019-01-31 02:11:49

标签: unity3d

我在2D游戏中使用A *寻路算法(据我了解,Unity Nav Meshes在2D中不起作用)。我希望能够为我的所有场景预先计算出导航网格,并将其保存在资源文件中,以便在播放器进入新场景时可以加载。无需记住要为每个场景单击“计算”-并记得在对导航网格进行更改后要重新计算所有场景-我希望能够以编程方式让Unity编辑器遍历每个场景并计算网格。

是否有一种方法可以在Unity编辑器中创建一个命令,该命令将迭代打开编辑器中的每个场景并在场景中的MonoBehaviour上运行一个方法?另外,还有另一种方法可以完成我想做的事情吗?

1 个答案:

答案 0 :(得分:4)

是的,可以的!

在编辑模式下,您不能使用SceneManager,而必须使用EditorSceneManager


首先,您需要迭代的场景。

例如检查器中的public static字段和SceneAsset的列表,您可以在其中简单地引用场景

public static List<SceneAsset> Scenes = new List<SceneAsset>();

,或者您可以通过脚本获取它们,例如仅使用通过EditorBuildSettings.scenes

添加到构建设置中的场景
List<EditorBuildSettingsScene> Scenes = EditorBuildSettings.scenes;

对于两者,您都可以获取场景路径列表,例如使用LinQ Select(基本上是foreach循环的一种快捷方式)和AssetDatabase.GetAssetPath

List<string> scenePaths = Scenes.Select(scene => AssetDatabase.GetAssetPath(scene)).ToList();

对于EditorBuildSettings.scenes中的EditorBuildSettingsScene,您也可以简单地使用

List<string> scenePaths = Scenes.Select(scene => scene.path).ToList();

现在,您可以遍历它们,并使用EditorSceneManager.OpenSceneEditorSceneManager.SaveSceneEditorSceneManager.CloseScene(如果需要,AssetDatabase.SaveAssets)来完成您的工作

foreach(string scenePath in scenePaths)
{
    // Open a scene e.g. in single mode
    var currentScene = EditorSceneManager.OpenScene(scenePath);

    /* Do your calculation for currentScene */

    // Don't know if it makes changes to your scenes .. if not you can probably skip this
    EditorSceneManager.SaveScene(currentScene);

    // Finally Close and remove the scene
    EditorSceneManager.CloseScene(currentScene, true);
}

// you might be doing changes to an asset you want to save when done
AssetDatabase.SaveAssets();

开始之前,您可能应该要求使用EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo

保存当前打开的场景。
if(EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
{
    // Saved => the foreach loop here
}
else
{
    // aborted => do nothing
}

要最终启动该方法,最简单的方法是添加一个[MenuItem]

public static class Calculation
{
    [MenuItem("YourMenu/RunCalculation")]
    public static void RunCalculation()
    {
        // all the before mentioned snippets here
        // depending how exactly you want to do it
    }
}

这将在Unity Editor的顶部菜单栏中添加一个新菜单YourMenu,其中有一个条目RunCalculation

注意:
由于这使用了仅存在于EditorSceneManager名称空间中的许多类型(UnityEditor等),因此您应该将整个脚本放在Editor文件夹中(因此在最终版本中将其忽略) )或使用

之类的预处理器
#if UNITY_EDITOR
    // ... code here
#endif

因此在构建中,代码也将被忽略。


请注意,到目前为止,我假设您也是在editmode下进行计算的。问题是,如果此计算依赖于任何StartAwake方法上的某个位置,则必须在运行计算之前从该编辑器脚本手动调用它。