Да, вы можете!
В режиме редактирования вы не можете использовать 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();
для EditorBuildSettingsScene изEditorBuildSettings.scenes
вы также можете просто использовать
List<string> scenePaths = Scenes.Select(scene => scene.path).ToList();
Теперь вы можете перебирать их все и делать свои вещи, используя EditorSceneManager.OpenScene
, EditorSceneManager.SaveScene
и EditorSceneManager.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
}
}
Это добавит новое меню YourMenu
с одной записью RunCalculation
в верхнюю строку меню редактора Unity.
Примечание:
Поскольку используетсяСуществует множество типов (EditorSceneManager
и т. д.), которые существуют только в пространстве имен UnityEditor
. Вы должны либо поместить весь сценарий в папку Editor
(чтобы он игнорировался в окончательной сборке), либо использовать препроцессоры, такие как
#if UNITY_EDITOR
// ... code here
#endif
, поэтому в сборке код также игнорируется.
Обратите внимание, что, как я полагаю, вы до сих пор делали вычисления в режиме редактирования.Дело в том, что если в этом расчете используется какой-либо метод Start
или Awake
, то вам нужно вызвать его вручную из этого редактора перед выполнением вычисления.