Update Setting

This commit is contained in:
2026-05-01 17:57:07 +07:00
parent bcb2c329c5
commit 9c784e77f8
26 changed files with 954 additions and 3233 deletions

View File

@@ -13,6 +13,9 @@ namespace Hallucinate.UI
{
public static BasicSpawner Instance { get; private set; }
private NetworkRunner _runner;
public NetworkRunner Runner => _runner;
private bool _isStarting = false;
public event Action<List<SessionInfo>> OnSessionListUpdatedEvent;
public event Action<string> OnShutdownEvent;
@@ -42,93 +45,125 @@ namespace Hallucinate.UI
private async Task EnsureRunnerExists()
{
if (_runner == null)
if (_runner != null)
{
_runner = GetComponent<NetworkRunner>();
}
if (_runner != null && _runner.IsRunning)
{
await _runner.Shutdown();
}
if (_runner == null)
{
_runner = gameObject.AddComponent<NetworkRunner>();
if (_runner.IsRunning)
{
Debug.Log("[BasicSpawner] Shutting down existing runner before recreation.");
await _runner.Shutdown();
}
Debug.Log("[BasicSpawner] Destroying existing runner component.");
Destroy(_runner);
_runner = null;
// Đợi 1 frame để đảm bảo component đã bị hủy thực sự
await Task.Yield();
}
Debug.Log("[BasicSpawner] Creating new NetworkRunner component.");
_runner = gameObject.AddComponent<NetworkRunner>();
_runner.ProvideInput = true;
_runner.RemoveCallbacks(this);
_runner.AddCallbacks(this);
}
public async Task StartLobby()
{
await EnsureRunnerExists();
if (_isStarting) return;
if (_runner.SessionInfo.IsValid) return;
// Nếu đã ở trong lobby rồi thì không cần làm gì
if (_runner != null && _runner.IsRunning && _runner.LobbyInfo.IsValid) return;
var result = await _runner.JoinSessionLobby(SessionLobby.ClientServer);
if (!result.Ok)
Debug.Log("[BasicSpawner] StartLobby called");
_isStarting = true;
try
{
Debug.LogWarning($"Join lobby result: {result.ShutdownReason}. This is often normal on first run if already connecting.");
await EnsureRunnerExists();
Debug.Log("[BasicSpawner] Joining Lobby...");
var result = await _runner.JoinSessionLobby(SessionLobby.ClientServer);
if (!result.Ok)
{
Debug.LogWarning($"Join lobby result: {result.ShutdownReason}");
}
}
finally
{
_isStarting = false;
}
}
public async Task<bool> StartHost(string sessionName, string displayName, string password = null)
{
OnJoinStartedEvent?.Invoke();
if (_isStarting) return false;
_isStarting = true;
bool sceneExists = false;
for (int i = 0; i < UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings; i++)
try
{
if (UnityEngine.SceneManagement.SceneUtility.GetScenePathByBuildIndex(i).Contains("Main Scene"))
Debug.Log($"[BasicSpawner] StartHost called: {sessionName} ({displayName})");
OnJoinStartedEvent?.Invoke();
bool sceneExists = false;
for (int i = 0; i < UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings; i++)
{
sceneExists = true;
break;
}
}
if (!sceneExists)
{
Debug.LogError("CRITICAL: 'Main Scene' is NOT in Build Settings!");
return false;
}
await EnsureRunnerExists();
var customProps = new Dictionary<string, SessionProperty>();
if (!string.IsNullOrEmpty(password))
{
customProps.Add("pw", password);
}
customProps.Add("rn", displayName);
var result = await _runner.StartGame(new StartGameArgs()
{
GameMode = GameMode.Host,
SessionName = sessionName,
SessionProperties = customProps,
PlayerCount = 2,
SceneManager = gameObject.GetComponent<NetworkSceneManagerDefault>() ?? gameObject.AddComponent<NetworkSceneManagerDefault>()
});
if (result.Ok)
{
if (_runner.IsServer && _playerDataManagerPrefab.IsValid)
{
if (FindFirstObjectByType<PlayerDataManager>() == null)
if (UnityEngine.SceneManagement.SceneUtility.GetScenePathByBuildIndex(i).Contains("Main Scene"))
{
_runner.Spawn(_playerDataManagerPrefab, Vector3.zero, Quaternion.identity, null);
sceneExists = true;
break;
}
}
return true;
if (!sceneExists)
{
Debug.LogError("CRITICAL: 'Main Scene' is NOT in Build Settings!");
return false;
}
await EnsureRunnerExists();
var customProps = new Dictionary<string, SessionProperty>();
if (!string.IsNullOrEmpty(password))
{
customProps.Add("pw", password);
}
customProps.Add("rn", displayName);
// Re-create or find SceneManager to ensure it matches the new runner
var sceneManager = gameObject.GetComponent<NetworkSceneManagerDefault>();
if (sceneManager == null) sceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>();
var result = await _runner.StartGame(new StartGameArgs()
{
GameMode = GameMode.Host,
SessionName = sessionName,
SessionProperties = customProps,
PlayerCount = 2,
SceneManager = sceneManager
});
if (result.Ok)
{
Debug.Log("[BasicSpawner] StartHost SUCCESS");
if (_runner.IsServer && _playerDataManagerPrefab.IsValid)
{
if (FindFirstObjectByType<PlayerDataManager>() == null)
{
Debug.Log("[BasicSpawner] Spawning PlayerDataManager");
_runner.Spawn(_playerDataManagerPrefab, Vector3.zero, Quaternion.identity, null);
}
}
return true;
}
else
{
Debug.LogError($"[BasicSpawner] Fusion StartHost Failed: {result.ShutdownReason}.");
OnJoinFailedEvent?.Invoke();
return false;
}
}
else
finally
{
Debug.LogError($"Fusion StartHost Failed: {result.ShutdownReason}.");
OnJoinFailedEvent?.Invoke();
return false;
_isStarting = false;
}
}
@@ -137,13 +172,17 @@ namespace Hallucinate.UI
OnJoinStartedEvent?.Invoke();
await EnsureRunnerExists();
var sceneManager = gameObject.GetComponent<NetworkSceneManagerDefault>();
if (sceneManager == null) sceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>();
var result = await _runner.StartGame(new StartGameArgs()
{
GameMode = GameMode.Client,
SessionName = sessionName,
SceneManager = gameObject.GetComponent<NetworkSceneManagerDefault>() ?? gameObject.AddComponent<NetworkSceneManagerDefault>()
SceneManager = sceneManager
});
if (result.Ok)
{
return true;