В 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. Важные замечания
Особенности работы:
- Build Settings обязательны - сцена должна быть добавлена в File → Build Settings
- Регистр не важен на Windows, но важен на других платформах
- Асинхронная загрузка - проверяйте существование перед асинхронной загрузкой
Рекомендации по использованию:
// Всегда проверяйте перед загрузкой 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.