using System.IO; using System.Threading.Tasks; using Sandbox.Gravity; using Sandbox; namespace Sandbox.UI; [Icon( "skip_next" )] public sealed class ChangeSceneButton : InteractionButton { /// /// Название сцены для загрузки /// [Property] public string SceneName { get; set; } = ""; /// /// Загружать сцену с задержкой (в секундах) /// [Property] public float LoadDelay { get; set; } = 0.0f; /// /// Показывать сообщение при загрузке сцены /// [Property] public bool ShowLoadingMessage { get; set; } = true; public override bool Press( IPressable.Event e ) { base.Press( e ); // Проверяем, что название сцены указано if ( string.IsNullOrWhiteSpace( SceneName ) ) { Log.Warning( "ChangeSceneButton: SceneName не указано!" ); return true; } // Формируем путь к сцене var scenePath = $"scenes/{SceneName}.scene"; // Логируем действие Log.Info( $"ChangeSceneButton: Подготавливаем сцену '{scenePath}'" ); // Показываем сообщение о загрузке if ( ShowLoadingMessage ) { Log.Info( $"Подготавливаем сцену: {scenePath}..." ); } // Загружаем сцену с задержкой или сразу if ( LoadDelay > 0.0f ) { _ = LoadSceneWithDelay(); } else { LoadScene(); } return true; } /// /// Загружает сцену с задержкой /// private async Task LoadSceneWithDelay() { await Task.Delay( (int)(LoadDelay * 1000) ); LoadScene(); } /// /// Загружает указанную сцену /// private void LoadScene() { try { // Проверяем, что код выполняется на сервере/хосте if ( !Networking.IsHost ) { Log.Warning( "ChangeSceneButton: Подготовка сцены возможна только на сервере/хосте!" ); return; } // Формируем путь к сцене var scenePath = $"scenes/{SceneName}.scene"; // Проверяем, существует ли файл сцены if ( !FileSystem.Mounted.FileExists( scenePath ) ) { Log.Error( $"Файл сцены не найден: {scenePath}" ); return; } // В s&box для смены сцены нужно использовать GameResource.Load // или перезапустить игру с новой сценой Log.Info( $"Файл сцены найден: {scenePath}" ); // Пока что просто логируем успех // В реальном проекте здесь нужно использовать GameResource.Load // или другой механизм смены сцены Log.Info( $"Сцена '{scenePath}' готова к загрузке!" ); Scene.Load( ResourceLibrary.Get( scenePath ) ); // TODO: Реализовать фактическую загрузку сцены // Например: GameResource.Load( scenePath ); } catch ( Exception ex ) { Log.Error( $"Ошибка при подготовке сцены '{SceneName}': {ex.Message}" ); } } /// /// Получает список доступных сцен для отображения в редакторе /// [Property, Category( "Debug" )] public void ListAvailableScenes() { Log.Info( "=== ДОСТУПНЫЕ СЦЕНЫ ===" ); // Получаем все сцены из папки scenes var sceneFiles = FileSystem.Mounted.FindFile( "scenes", "*.scene" ); if ( sceneFiles == null || !sceneFiles.Any() ) { Log.Info( "Сцены не найдены в папке scenes/" ); return; } foreach ( var sceneFile in sceneFiles ) { var sceneName = Path.GetFileNameWithoutExtension( sceneFile ); Log.Info( $" - {sceneName}" ); } Log.Info( "=======================" ); } /// /// Тестирует загрузку сцены (для отладки) /// [Property, Category( "Debug" )] public void TestSceneLoad() { if ( string.IsNullOrWhiteSpace( SceneName ) ) { Log.Warning( "SceneName не указано для тестирования!" ); return; } Log.Info( $"=== ТЕСТ ПОДГОТОВКИ СЦЕНЫ '{SceneName}' ===" ); var scenePath = $"scenes/{SceneName}.scene"; Log.Info( $"Путь к сцене: {scenePath}" ); Log.Info( $"Файл существует: {FileSystem.Mounted.FileExists( scenePath )}" ); Log.Info( $"IsHost: {Networking.IsHost}" ); Log.Info( $"IsClient: {Networking.IsClient}" ); Log.Info( $"IsActive: {Networking.IsActive}" ); Log.Info( "=== ТЕСТ ЗАВЕРШЕН ===" ); } }