Многостадийный запуск сборки, как есть, из Unity, как? - PullRequest
0 голосов
/ 03 февраля 2019

Мультисценовое редактирование в Unity, благословенно это, позволяет запускать (через режим Play Editor) текущие сцены в их текущем иерархическом состоянии.

Однако сборка и запуск проекта не распознаюттекущая настройка сцены в редакторе и начинается с того, что установлено в настройках сборки.

Есть ли какой-нибудь способ, позволяющий сборкам узнавать о текущем состоянии редактора иерархии редактирования нескольких сцен, а также создавать и запускать эту настройку

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

1.Получение сцен редактора в настройках сборки

Сначала для сбора настроек вы можете использовать скрипт редактора, используя

  • EditorSceneManager.GetSceneManagerSetup для получения текущей настройкисцены в редакторе
  • Я предполагаю, что вам нужны только loaded Сцены, поэтому составьте список только сцен с isLoaded = true
  • EditorBuildSettings.scenes чтобы добавить эти сцены в настройки сборки

1.a.Обновление по MenuItem нажмите

Я сделал ее дополнительной кнопкой в ​​меню, так как вы можете не захотеть, чтобы она была всегда автоматически.

using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.SceneManagement;

public static class UpdateBuildSettigns
{
    [MenuItem("Example/UpdateBuildSettings")]
    public static void UpdateSettings()
    {
        // get current editor setup
        SceneSetup[] editorScenes = EditorSceneManager.GetSceneManagerSetup();

        // filter list e.g. get only scenes with isActive true
        var activeEditorScenes = editorScenes.Where(scene => scene.isLoaded);

        // set those scenes as the buildsettings
        List<EditorBuildSettingsScene> editorBuildSettingsScenes = new List<EditorBuildSettingsScene>();
        foreach (var sceneAsset in activeEditorScenes)
        {
            string scenePath = sceneAsset.path;

            // ignore unsaved scenes
            if (!string.IsNullOrEmpty(scenePath)) continue;

            editorBuildSettingsScenes.Add(new EditorBuildSettingsScene(scenePath, true));
        }

        // Set the Build Settings window Scene list
        EditorBuildSettings.scenes = editorBuildSettingsScenes.ToArray();
    }
}

Обновление по кнопке меню

enter image description here


1.b.Обновлять автоматически при (не) загрузке сцен

Если вы хотите, чтобы это происходило автоматически, вы также можете добавить вызов в качестве обратного вызова в EditorSceneManager.sceneOpened и EditorSceneManager.sceneClosed , используя InitializeOnLoad и статический конструктор для добавления обратных вызовов после перекомпиляции или открытия UnityEditor, например

using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;

[InitializeOnLoad]
public static class UpdateBuildSettigns
{
    // ofcourse you still can also call it via menu item
    [MenuItem("Example/UpdateBuildSettings")]
    public static void UpdateSettings()
    {
        //...
    }

    static UpdateBuildSettigns()
    {
        // it is always save to remove callbacks even if they are not there
        // makes sure they are always only added once
        //
        // this is a static constructor so actually there should be no
        // callbacks yet ... but .. you never know ;)
        EditorSceneManager.sceneOpened -= OnSceneLoaded;
        EditorSceneManager.sceneClosed -= OnSceneUnloaded;

        EditorSceneManager.sceneOpened += OnSceneLoaded;
        EditorSceneManager.sceneClosed += OnSceneUnloaded;
    }

    private static void OnSceneUnloaded(Scene current)
    {
        UpdateSettings();
    }

    private static void OnSceneLoaded(Scene current, OpenSceneMode mode)
    {
        UpdateSettings();
    }
}

Использование автоматического обновления

enter image description here


1.c.Включение / отключение автоматических обновлений

Если вы хотите больше контроля, вы также можете добавить дополнительные пункты меню для включения и отключения автоматических обновлений, такие как

// flag to check if auto-updates are currently enabled
private static bool isEnabled;

// disable the "EnableAutoUpdate" button if already enabled
[MenuItem("Example/EnableAutoUpdate", true)]
private static bool CanEnable()
{
    return !isEnabled;
}

// disable the "DisableAutoUpdate" button if already disabled
[MenuItem("Example/DisableAutoUpdate", true)]
private static bool CanDisable()
{
    return isEnabled;
}

// add callbacks
[MenuItem("Example/EnableAutoUpdate")]
private static void EnableAutoUpdate()
{
    // it is always save to remove callbacks even if they are not there
    // makes sure they are always only added once
    EditorSceneManager.sceneOpened -= OnSceneLoaded;
    EditorSceneManager.sceneClosed -= OnSceneUnloaded;

    EditorSceneManager.sceneOpened += OnSceneLoaded;
    EditorSceneManager.sceneClosed += OnSceneUnloaded;

    isEnabled = true;
}

// remove callbacks
[MenuItem("Example/DisableAutoUpdate")]
private static void DisableAutoUpdate()
{
    EditorSceneManager.sceneOpened -= OnSceneLoaded;
    EditorSceneManager.sceneClosed -= OnSceneUnloaded;

    isEnabled = false;
}

Примечание, так как при этом используется UnityEditor namespace вы должны либо поместить этот скрипт в папку Editor, либо использовать соответствующие препроцессоры, такие как

#if UNITY_EDITOR

// above code here

#endif

2.Загрузка всех сцен из настроек сборки

Чем позже при запуске приложения в первой сцене должен быть скрипт, отвечающий за загрузку всех этих сцен.Например,

// making it a component to make sure it is inside of one scene
public class SceneLoader : MonoBehaviour
{
    private void Start()
    {
        var thisScene = SceneManager.GetActiveScene();

        // load all scenes
        for(int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
        {
            // skip if is current scene since we don't want it twice
            if(thisScene.buildIndex == i) continue;

             // Skip if scene is already loaded
            if(SceneManager.GetSceneByBuildIndex(i).IsValid()) continue;

            SceneManager.LoadScene(i, LoadSceneMode.Additive);
            // or depending on your usecase
            SceneManager.LoadSceneAsync(i, LoadSceneMode.Additive);
        }
    }
}

ссылки:

0 голосов
/ 05 февраля 2019

То, что я хотел бы сделать, это прикрепить какой-то скрипт к стартовой сцене в единстве, который затем запустит загрузку остальных необходимых сцен после запуска игры.Это потребовало бы некоторого перебора для правильного запуска (например, обнаружение того факта, что сцены еще не загружены, прежде чем пытаться загрузить их).

Я мог бы расширить ответ с помощью фрагмента кода для достижения результата, если он вам нужен.

Пока вы можете посмотреть документы здесь: https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.GetSceneByName.html https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadSceneAsync.html

Основная идея будет такой:

  1. Получитьнеобходимые сцены с помощью SceneManager.GetSceneByName и отфильтруйте все сцены, которые уже загружены.
  2. Для сцен, которые еще не загружены, вызовите LoadSceneAsync и присоедините некоторую сопрограмму для проверки хода загрузки.
  3. Когда все сцены загружены, запустите обратный вызов, чтобы остальная часть игры знала, что сцены загружены, и хорошо выполнить остальные необходимые действия, которые зависят от загрузки этих сцен.

Если вы хотите сохранить текущую иерархию (набор сцен, которые открываются в редакторе) при построении, то это может быть достигнуто с помощьюBuildPipeline: https://docs.unity3d.com/Manual/BuildPlayerPipeline.html

Существует способ сделать сборку с программно-доступным списком сцен:

 // Get filename.
 string path = EditorUtility.SaveFolderPanel("Choose Location of Built Game", "", "");
 string[] levels = new string[] {"Assets/Scene1.unity", "Assets/Scene2.unity"}; // You'd have to assemble this list yourself.
 // Build player.
 BuildPipeline.BuildPlayer(levels, path + "/BuiltGame.exe", BuildTarget.StandaloneWindows, BuildOptions.None);

(который можно определить на основе загруженных в данный момент сцен при запускеваша сборка).Это не стандартная (Cmd + b) сборка, но довольно близкая.

...