Как в юнити проверить существование сцены по названию?

В Unity для проверки существования сцены по названию существует несколько подходов. Вот подробное объяснение различных методов:

1. Использование Build Settings (Рекомендуемый способ)

Основной метод:

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneChecker : MonoBehaviour
{
    public bool CheckSceneExists(string sceneName)
    {
        // Проверяем, добавлена ли сцена в Build Settings
        for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
        {
            string scenePath = SceneUtility.GetScenePathByBuildIndex(i);
            string currentSceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath);
            
            if (currentSceneName == sceneName)
            {
                return true;
            }
        }
        return false;
    }
}

Усовершенствованная версия с кэшированием:

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

public class SceneManagerHelper : MonoBehaviour
{
    private static Dictionary<string, bool> sceneCache = new Dictionary<string, bool>();
    private static bool isCacheBuilt = false;

    public static bool SceneExists(string sceneName)
    {
        // Строим кэш при первом вызове
        if (!isCacheBuilt)
        {
            BuildSceneCache();
        }

        // Проверяем наличие в кэше
        return sceneCache.ContainsKey(sceneName) && sceneCache[sceneName];
    }

    private static void BuildSceneCache()
    {
        sceneCache.Clear();
        
        for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
        {
            string scenePath = SceneUtility.GetScenePathByBuildIndex(i);
            string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath);
            
            sceneCache[sceneName] = true;
        }
        
        isCacheBuilt = true;
    }

    // Метод для обновления кэша при изменении Build Settings
    public static void RefreshSceneCache()
    {
        isCacheBuilt = false;
        BuildSceneCache();
    }
}

2. Альтернативный подход с использованием SceneUtility

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneValidation
{
    public static bool IsSceneInBuildSettings(string sceneName)
    {
        try
        {
            // Пытаемся получить индекс сцены
            int sceneIndex = SceneUtility.GetBuildIndexByScenePath(sceneName);
            return sceneIndex >= 0;
        }
        catch
        {
            return false;
        }
    }
}

3. Полный пример использования

using UnityEngine;
using UnityEngine.SceneManagement;

public class ExampleUsage : MonoBehaviour
{
    [SerializeField] private string targetSceneName = "MainMenu";

    void Start()
    {
        CheckAndLoadScene();
    }

    void CheckAndLoadScene()
    {
        if (SceneExists(targetSceneName))
        {
            Debug.Log($"Сцена '{targetSceneName}' существует в Build Settings");
            
            // Загружаем сцену
            SceneManager.LoadScene(targetSceneName);
        }
        else
        {
            Debug.LogError($"Сцена '{targetSceneName}' не найдена в Build Settings!");
            Debug.Log("Пожалуйста, добавьте сцену в File → Build Settings");
        }
    }

    bool SceneExists(string sceneName)
    {
        if (string.IsNullOrEmpty(sceneName))
            return false;

        for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
        {
            var scenePath = SceneUtility.GetScenePathByBuildIndex(i);
            var lastSlash = scenePath.LastIndexOf("/");
            var name = scenePath.Substring(lastSlash + 1, scenePath.LastIndexOf(".") - lastSlash - 1);
            
            if (string.Compare(name, sceneName, true) == 0)
                return true;
        }
        
        return false;
    }
}

4. Editor Script для проверки в редакторе

#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;

public class SceneValidationEditor : EditorWindow
{
    [MenuItem("Tools/Scene Validator")]
    public static void ShowWindow()
    {
        GetWindow<SceneValidationEditor>("Scene Validator");
    }

    private string sceneNameToCheck = "";

    void OnGUI()
    {
        GUILayout.Label("Проверка существования сцены", EditorStyles.boldLabel);
        
        sceneNameToCheck = EditorGUILayout.TextField("Название сцены:", sceneNameToCheck);
        
        if (GUILayout.Button("Проверить"))
        {
            bool exists = CheckSceneInBuildSettings(sceneNameToCheck);
            
            if (exists)
            {
                EditorUtility.DisplayDialog("Результат", 
                    $"Сцена '{sceneNameToCheck}' найдена в Build Settings!", "OK");
            }
            else
            {
                EditorUtility.DisplayDialog("Результат", 
                    $"Сцена '{sceneNameToCheck}' не найдена!", "OK");
            }
        }
    }

    private bool CheckSceneInBuildSettings(string sceneName)
    {
        foreach (var scene in EditorBuildSettings.scenes)
        {
            if (scene.path.EndsWith("/" + sceneName + ".unity"))
                return true;
        }
        return false;
    }
}
#endif

5. Важные замечания

Особенности работы:

  1. Build Settings обязательны - сцена должна быть добавлена в File → Build Settings
  2. Регистр не важен на Windows, но важен на других платформах
  3. Асинхронная загрузка - проверяйте существование перед асинхронной загрузкой

Рекомендации по использованию:

// Всегда проверяйте перед загрузкой
if (SceneExists("GameLevel"))
{
    SceneManager.LoadScene("GameLevel");
}
else
{
    Debug.LogError("Сцена GameLevel не найдена!");
}

// Для асинхронной загрузки
if (SceneExists("LoadingScreen"))
{
    StartCoroutine(LoadSceneAsync("LoadingScreen"));
}

6. Расширенная утилита для работы со сценами

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

public static class SceneUtilities
{
    public static bool SceneExists(string sceneName)
    {
        if (string.IsNullOrEmpty(sceneName)) return false;
        
        for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
        {
            if (GetSceneNameFromIndex(i) == sceneName)
                return true;
        }
        return false;
    }

    public static string GetSceneNameFromIndex(int buildIndex)
    {
        string path = SceneUtility.GetScenePathByBuildIndex(buildIndex);
        int slashIndex = path.LastIndexOf('/');
        string name = path.Substring(slashIndex + 1);
        int dotIndex = name.LastIndexOf('.');
        return name.Substring(0, dotIndex);
    }

    public static List<string> GetAllSceneNames()
    {
        List<string> sceneNames = new List<string>();
        
        for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++)
        {
            sceneNames.Add(GetSceneNameFromIndex(i));
        }
        
        return sceneNames;
    }
}

Эти методы предоставляют надежные способы проверки существования сцен в Unity. Рекомендую использовать первый подход с кэшированием для оптимальной производительности, особенно если проверка выполняется frequently.