Update
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@@ -19,6 +19,10 @@ namespace Hallucinate.UI
|
||||
public event Action OnJoinStartedEvent;
|
||||
public event Action OnJoinFailedEvent;
|
||||
|
||||
[Header(""Prefabs"")]
|
||||
[SerializeField] private NetworkPrefabRef _playerPrefab;
|
||||
[SerializeField] private NetworkPrefabRef _playerDataManagerPrefab;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
@@ -62,22 +66,23 @@ namespace Hallucinate.UI
|
||||
{
|
||||
await EnsureRunnerExists();
|
||||
|
||||
if (_runner.SessionInfo.IsValid) return;
|
||||
|
||||
var result = await _runner.JoinSessionLobby(SessionLobby.ClientServer);
|
||||
if (!result.Ok)
|
||||
{
|
||||
Debug.LogError($"Failed to join lobby: {result.ShutdownReason}. Check AppID type or Network/Firewall.");
|
||||
Debug.LogWarning($""Join lobby result: {result.ShutdownReason}. This is often normal on first run if already connecting."");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> StartHost(string sessionName, string password = null)
|
||||
public async Task<bool> StartHost(string sessionName, string displayName, string password = null)
|
||||
{
|
||||
OnJoinStartedEvent?.Invoke();
|
||||
|
||||
// 1. Kiểm tra Build Settings
|
||||
bool sceneExists = false;
|
||||
for (int i = 0; i < UnityEngine.SceneManagement.SceneManager.sceneCountInBuildSettings; i++)
|
||||
{
|
||||
if (UnityEngine.SceneManagement.SceneUtility.GetScenePathByBuildIndex(i).Contains("Main Scene"))
|
||||
if (UnityEngine.SceneManagement.SceneUtility.GetScenePathByBuildIndex(i).Contains(""Main Scene""))
|
||||
{
|
||||
sceneExists = true;
|
||||
break;
|
||||
@@ -86,18 +91,18 @@ namespace Hallucinate.UI
|
||||
|
||||
if (!sceneExists)
|
||||
{
|
||||
Debug.LogError("CRITICAL: 'Main Scene' is NOT in Build Settings!");
|
||||
Debug.LogError(""CRITICAL: 'Main Scene' is NOT in Build Settings!"");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. Khởi tạo Runner mới sạch sẽ
|
||||
await EnsureRunnerExists();
|
||||
|
||||
var customProps = new Dictionary<string, SessionProperty>();
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
customProps.Add("pw", password);
|
||||
customProps.Add(""pw"", password);
|
||||
}
|
||||
customProps.Add(""rn"", displayName);
|
||||
|
||||
var result = await _runner.StartGame(new StartGameArgs()
|
||||
{
|
||||
@@ -105,18 +110,23 @@ namespace Hallucinate.UI
|
||||
SessionName = sessionName,
|
||||
SessionProperties = customProps,
|
||||
PlayerCount = 2,
|
||||
// Thêm fixed region để tránh timeout khi tìm server
|
||||
// SceneManager sẽ tự động add nếu thiếu
|
||||
SceneManager = gameObject.GetComponent<NetworkSceneManagerDefault>() ?? gameObject.AddComponent<NetworkSceneManagerDefault>()
|
||||
});
|
||||
|
||||
if (result.Ok)
|
||||
{
|
||||
if (_runner.IsServer && _playerDataManagerPrefab.IsValid)
|
||||
{
|
||||
if (FindFirstObjectByType<PlayerDataManager>() == null)
|
||||
{
|
||||
_runner.Spawn(_playerDataManagerPrefab, Vector3.zero, Quaternion.identity, null);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Fusion StartHost Failed: {result.ShutdownReason}.");
|
||||
Debug.LogError($""Fusion StartHost Failed: {result.ShutdownReason}."");
|
||||
OnJoinFailedEvent?.Invoke();
|
||||
return false;
|
||||
}
|
||||
@@ -140,39 +150,54 @@ namespace Hallucinate.UI
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Fusion StartClient Failed: {result.ShutdownReason}");
|
||||
Debug.LogError($""Fusion StartClient Failed: {result.ShutdownReason}"");
|
||||
OnJoinFailedEvent?.Invoke();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Các phương thức Callbacks ---
|
||||
[SerializeField] private NetworkPrefabRef _playerPrefab;
|
||||
private Dictionary<PlayerRef, NetworkObject> _spawnedCharacters = new Dictionary<PlayerRef, NetworkObject>();
|
||||
|
||||
public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
if (player == runner.LocalPlayer)
|
||||
{
|
||||
var pdm = FindFirstObjectByType<PlayerDataManager>();
|
||||
if (pdm != null)
|
||||
SendLocalMetaData(player);
|
||||
}
|
||||
}
|
||||
|
||||
private async void SendLocalMetaData(PlayerRef player)
|
||||
{
|
||||
PlayerDataManager pdm = null;
|
||||
int retries = 0;
|
||||
while (pdm == null && retries < 20)
|
||||
{
|
||||
pdm = FindFirstObjectByType<PlayerDataManager>();
|
||||
if (pdm != null) break;
|
||||
await Task.Delay(500);
|
||||
retries++;
|
||||
}
|
||||
|
||||
if (pdm != null)
|
||||
{
|
||||
string playerName = LocalPlayerProfile != null ? LocalPlayerProfile.Name : ""Player "" + player.PlayerId;
|
||||
|
||||
// Thêm hậu tố (HOST) nếu là server để dễ phân biệt
|
||||
if (_runner.IsServer) playerName += "" (HOST)"";
|
||||
|
||||
_Role playerRole = _Role.Seeker;
|
||||
|
||||
var metaData = new _PlayerMetaData()
|
||||
{
|
||||
string playerName = "Player";
|
||||
_Role playerRole = _Role.Seeker;
|
||||
|
||||
if (LocalPlayerProfile != null)
|
||||
{
|
||||
playerName = LocalPlayerProfile.Name;
|
||||
}
|
||||
|
||||
var metaData = new _PlayerMetaData()
|
||||
{
|
||||
Name = playerName,
|
||||
Role = playerRole,
|
||||
IsReady = false
|
||||
};
|
||||
pdm.RPC_UpdatePlayerMetaData(player, metaData);
|
||||
}
|
||||
Name = playerName,
|
||||
Role = playerRole,
|
||||
IsReady = false
|
||||
};
|
||||
pdm.RPC_UpdatePlayerMetaData(player, metaData);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError(""[BasicSpawner] Could not find PlayerDataManager after retries. Data will not sync."");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +205,7 @@ namespace Hallucinate.UI
|
||||
{
|
||||
if (_runner != null && _runner.IsServer)
|
||||
{
|
||||
_runner.LoadScene("Main Scene");
|
||||
_runner.LoadScene(""Main Scene"");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,18 +215,23 @@ namespace Hallucinate.UI
|
||||
{
|
||||
runner.Despawn(networkObject);
|
||||
_spawnedCharacters.Remove(player);
|
||||
// Chỉ Shutdown nếu người thoát chính là Server (Host)
|
||||
if (runner.IsServer && player == runner.LocalPlayer)
|
||||
{
|
||||
runner.Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
if (runner.IsServer && player == runner.LocalPlayer)
|
||||
{
|
||||
runner.Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason)
|
||||
{
|
||||
Debug.LogWarning($"[Fusion] Shutdown occurred. Reason: {shutdownReason}");
|
||||
Debug.LogWarning($""[Fusion] Shutdown occurred. Reason: {shutdownReason}"");
|
||||
OnShutdownEvent?.Invoke(shutdownReason.ToString());
|
||||
|
||||
if (UIManager.Instance != null)
|
||||
{
|
||||
UIManager.Instance.OnBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList)
|
||||
@@ -238,7 +268,7 @@ namespace Hallucinate.UI
|
||||
public void OnSceneLoadDone(NetworkRunner runner)
|
||||
{
|
||||
string currentSceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
|
||||
if (runner.IsServer && currentSceneName == "Main Scene")
|
||||
if (runner.IsServer && currentSceneName == ""Main Scene"")
|
||||
{
|
||||
foreach (var player in runner.ActivePlayers)
|
||||
{
|
||||
@@ -247,9 +277,9 @@ namespace Hallucinate.UI
|
||||
_spawnedCharacters.Add(player, networkPlayerObject);
|
||||
}
|
||||
}
|
||||
if (currentSceneName == "Main Scene")
|
||||
if (currentSceneName == ""Main Scene"")
|
||||
UIManager.Instance?.OnGameStarted();
|
||||
else if (currentSceneName == "Lobby" || currentSceneName == "Menu")
|
||||
else if (currentSceneName == ""Lobby"" || currentSceneName == ""Menu"")
|
||||
UIManager.Instance?.OnBackToMenu();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user