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( "=== ТЕСТ ЗАВЕРШЕН ===" );
}
}