Update
This commit is contained in:
@@ -9,9 +9,10 @@ using OnlyScove.Scripts;
|
||||
|
||||
namespace Hallucinate.UI
|
||||
{
|
||||
public class _BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
|
||||
public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
|
||||
{
|
||||
private NetworkRunner _runner { get; set; }
|
||||
public static BasicSpawner Instance { get; private set; }
|
||||
private NetworkRunner _runner;
|
||||
|
||||
public event Action<List<SessionInfo>> OnSessionListUpdatedEvent;
|
||||
public event Action<string> OnShutdownEvent;
|
||||
@@ -20,29 +21,74 @@ namespace Hallucinate.UI
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (_runner == null) _runner = gameObject.AddComponent<NetworkRunner>();
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
public _PlayerProfile LocalPlayerProfile { get; private set; }
|
||||
public void SetLocalPlayerProfile(_PlayerProfile _profile)
|
||||
public PlayerProfile LocalPlayerProfile { get; private set; }
|
||||
public void SetLocalPlayerProfile(PlayerProfile _profile)
|
||||
{
|
||||
LocalPlayerProfile = _profile;
|
||||
}
|
||||
|
||||
public async Task StartLobby()
|
||||
private async Task EnsureRunnerExists()
|
||||
{
|
||||
if (_runner == null) _runner = gameObject.AddComponent<NetworkRunner>();
|
||||
if (_runner != null)
|
||||
{
|
||||
// Nếu runner cũ vẫn đang chạy hoặc lỗi, dọn dẹp nó
|
||||
await _runner.Shutdown();
|
||||
if (_runner != null && _runner.gameObject != null)
|
||||
{
|
||||
Destroy(_runner);
|
||||
}
|
||||
_runner = null;
|
||||
}
|
||||
|
||||
_runner = gameObject.AddComponent<NetworkRunner>();
|
||||
_runner.ProvideInput = true;
|
||||
_runner.AddCallbacks(this);
|
||||
var result = await _runner.JoinSessionLobby(SessionLobby.ClientServer);
|
||||
if (!result.Ok) Debug.LogError($"Failed to join lobby: {result.ShutdownReason}");
|
||||
}
|
||||
|
||||
public async Task StartHost(string sessionName, string password = null)
|
||||
public async Task StartLobby()
|
||||
{
|
||||
await EnsureRunnerExists();
|
||||
|
||||
var result = await _runner.JoinSessionLobby(SessionLobby.ClientServer);
|
||||
if (!result.Ok)
|
||||
{
|
||||
Debug.LogError($"Failed to join lobby: {result.ShutdownReason}. Check AppID type or Network/Firewall.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> StartHost(string sessionName, 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"))
|
||||
{
|
||||
sceneExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sceneExists)
|
||||
{
|
||||
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))
|
||||
{
|
||||
@@ -55,34 +101,48 @@ namespace Hallucinate.UI
|
||||
SessionName = sessionName,
|
||||
SessionProperties = customProps,
|
||||
PlayerCount = 2,
|
||||
SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()
|
||||
// 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 (result.Ok)
|
||||
{
|
||||
Debug.LogError($"Failed to start host: {result.ShutdownReason}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Fusion StartHost Failed: {result.ShutdownReason}.");
|
||||
OnJoinFailedEvent?.Invoke();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task StartClient(string sessionName, string password = null)
|
||||
public async Task<bool> StartClient(string sessionName, string password = null)
|
||||
{
|
||||
OnJoinStartedEvent?.Invoke();
|
||||
await EnsureRunnerExists();
|
||||
|
||||
var result = await _runner.StartGame(new StartGameArgs()
|
||||
{
|
||||
GameMode = GameMode.Client,
|
||||
SessionName = sessionName,
|
||||
SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()
|
||||
SceneManager = gameObject.GetComponent<NetworkSceneManagerDefault>() ?? gameObject.AddComponent<NetworkSceneManagerDefault>()
|
||||
});
|
||||
|
||||
if (!result.Ok)
|
||||
if (result.Ok)
|
||||
{
|
||||
Debug.LogError($"Failed to join client: {result.ShutdownReason}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
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>();
|
||||
|
||||
@@ -90,13 +150,21 @@ namespace Hallucinate.UI
|
||||
{
|
||||
if (player == runner.LocalPlayer)
|
||||
{
|
||||
var pdm = FindFirstObjectByType<_PlayerDataManager>();
|
||||
var pdm = FindFirstObjectByType<PlayerDataManager>();
|
||||
if (pdm != null)
|
||||
{
|
||||
string playerName = "Player";
|
||||
_Role playerRole = _Role.Seeker;
|
||||
|
||||
if (LocalPlayerProfile != null)
|
||||
{
|
||||
playerName = LocalPlayerProfile.Name;
|
||||
}
|
||||
|
||||
var metaData = new _PlayerMetaData()
|
||||
{
|
||||
Name = LocalPlayerProfile.Name,
|
||||
Role = LocalPlayerProfile.Role,
|
||||
Name = playerName,
|
||||
Role = playerRole,
|
||||
IsReady = false
|
||||
};
|
||||
pdm.RPC_UpdatePlayerMetaData(player, metaData);
|
||||
@@ -106,7 +174,7 @@ namespace Hallucinate.UI
|
||||
|
||||
public void StartGame()
|
||||
{
|
||||
if (_runner.IsServer)
|
||||
if (_runner != null && _runner.IsServer)
|
||||
{
|
||||
_runner.LoadScene("Main Scene");
|
||||
}
|
||||
@@ -135,26 +203,13 @@ namespace Hallucinate.UI
|
||||
public void OnInput(NetworkRunner runner, NetworkInput input)
|
||||
{
|
||||
var data = new PlayerInputData();
|
||||
|
||||
// Try to get input from the local player's InputReader
|
||||
if (PlayerStateMachine.Local != null && PlayerStateMachine.Local.Input != null)
|
||||
{
|
||||
var inputReader = PlayerStateMachine.Local.Input;
|
||||
data.Direction = inputReader.MoveInput;
|
||||
data.sprint = inputReader.IsSprintHeld;
|
||||
|
||||
data.Direction = PlayerStateMachine.Local.Input.MoveInput;
|
||||
data.sprint = PlayerStateMachine.Local.Input.IsSprintHeld;
|
||||
if (PlayerStateMachine.Local.Cam != null)
|
||||
{
|
||||
data.rot = PlayerStateMachine.Local.Cam.PlanarRotation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback to basic input if player not spawned or InputReader missing
|
||||
data.Direction = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
|
||||
data.sprint = Input.GetKey(KeyCode.LeftShift);
|
||||
}
|
||||
|
||||
input.Set(data);
|
||||
}
|
||||
|
||||
@@ -174,7 +229,6 @@ namespace Hallucinate.UI
|
||||
public void OnSceneLoadDone(NetworkRunner runner)
|
||||
{
|
||||
string currentSceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
|
||||
|
||||
if (runner.IsServer && currentSceneName == "Main Scene")
|
||||
{
|
||||
foreach (var player in runner.ActivePlayers)
|
||||
@@ -184,15 +238,10 @@ namespace Hallucinate.UI
|
||||
_spawnedCharacters.Add(player, networkPlayerObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentSceneName == "Main Scene")
|
||||
{
|
||||
if (UIManager.Instance != null) UIManager.Instance.OnGameStarted();
|
||||
}
|
||||
UIManager.Instance?.OnGameStarted();
|
||||
else if (currentSceneName == "Lobby" || currentSceneName == "Menu")
|
||||
{
|
||||
if (UIManager.Instance != null) UIManager.Instance.OnBackToMenu();
|
||||
}
|
||||
UIManager.Instance?.OnBackToMenu();
|
||||
}
|
||||
|
||||
public void OnSceneLoadStart(NetworkRunner runner) { }
|
||||
@@ -1,7 +1,7 @@
|
||||
using Fusion;
|
||||
using UnityEngine;
|
||||
|
||||
public class _PlayerData : NetworkBehaviour
|
||||
public class PlayerData : NetworkBehaviour
|
||||
{
|
||||
[Networked]
|
||||
public _Role PlayerRole { get; set; }
|
||||
@@ -9,7 +9,7 @@ public struct _PlayerMetaData : INetworkStruct
|
||||
public NetworkBool IsReady;
|
||||
}
|
||||
|
||||
public class _PlayerDataManager : NetworkBehaviour
|
||||
public class PlayerDataManager : NetworkBehaviour
|
||||
{
|
||||
[Networked]
|
||||
public NetworkDictionary<PlayerRef, _PlayerMetaData> Players => default;
|
||||
@@ -8,17 +8,18 @@ public enum _Role
|
||||
Trapper
|
||||
}
|
||||
|
||||
public struct _PlayerProfile
|
||||
[System.Serializable]
|
||||
public class PlayerProfile
|
||||
{
|
||||
public string Name;
|
||||
public _Role Role;
|
||||
public string Name = "Player";
|
||||
public _Role Role = _Role.Seeker;
|
||||
}
|
||||
|
||||
public class _PlayerInfo : NetworkBehaviour
|
||||
public class PlayerInfo : NetworkBehaviour
|
||||
{
|
||||
[Networked] public string playerName { get; set; }
|
||||
|
||||
public _PlayerDataManager playerDataManager;
|
||||
public PlayerDataManager playerDataManager;
|
||||
public TextMeshProUGUI nameText;
|
||||
|
||||
public GameObject[] characterIcons; // mảng chứa icon tương ứng với từng class, có thể gán trong inspector
|
||||
@@ -27,7 +28,7 @@ public class _PlayerInfo : NetworkBehaviour
|
||||
// sẽ gọi phương thức này để khởi tạo thông tin player
|
||||
public override void Spawned()
|
||||
{
|
||||
playerDataManager = FindFirstObjectByType<_PlayerDataManager>(); // tìm PlayerDataManager trong scene
|
||||
playerDataManager = FindFirstObjectByType<PlayerDataManager>(); // tìm PlayerDataManager trong scene
|
||||
}
|
||||
|
||||
// phương thức này sẽ được gọi mỗi frame để cập nhật thông tin hiển thị của player
|
||||
@@ -39,12 +40,17 @@ public class _PlayerInfo : NetworkBehaviour
|
||||
var name = metadata.Name;
|
||||
var charClass = metadata.Role;
|
||||
|
||||
nameText.text = $"{name} ({charClass})";
|
||||
if (nameText != null)
|
||||
nameText.text = $"{name} ({charClass})";
|
||||
|
||||
for (var i = 0; i < characterIcons.Length; i++)
|
||||
if (characterIcons != null)
|
||||
{
|
||||
characterIcons[i].SetActive(i == (int)charClass); // hiển thị icon tương ứng với class của player
|
||||
for (var i = 0; i < characterIcons.Length; i++)
|
||||
{
|
||||
if (characterIcons[i] != null)
|
||||
characterIcons[i].SetActive(i == (int)charClass); // hiển thị icon tương ứng với class của player
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,7 @@ namespace Hallucinate.UI
|
||||
public class LobbyController : BaseUIController
|
||||
{
|
||||
private VisualTreeAsset _roomItemTemplate;
|
||||
private _BasicSpawner _spawner;
|
||||
private _PlayerDataManager _playerDataManager;
|
||||
private PlayerDataManager _playerDataManager;
|
||||
|
||||
// Containers
|
||||
private VisualElement _joinContainer, _createContainer, _loungeContainer, _passOverlay;
|
||||
@@ -34,7 +33,6 @@ namespace Hallucinate.UI
|
||||
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
|
||||
{
|
||||
base.Initialize(uxmlRoot, manager);
|
||||
_spawner = Object.FindFirstObjectByType<_BasicSpawner>();
|
||||
|
||||
// Query Elements
|
||||
_joinContainer = root.Q<VisualElement>("JoinContainer");
|
||||
@@ -91,13 +89,24 @@ namespace Hallucinate.UI
|
||||
});
|
||||
}
|
||||
|
||||
// Đăng ký sự kiện từ Spawner
|
||||
if (_spawner != null)
|
||||
// Đăng ký sự kiện từ Spawner (Sử dụng Instance)
|
||||
if (BasicSpawner.Instance != null)
|
||||
{
|
||||
_spawner.OnSessionListUpdatedEvent += UpdateRoomList;
|
||||
_spawner.OnJoinFailedEvent += () => _joinPassError.style.display = DisplayStyle.Flex;
|
||||
_spawner.OnJoinStartedEvent += () => { /* Show loading if needed */ };
|
||||
RegisterSpawnerEvents();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nếu chưa có, thử tìm sau một chút
|
||||
Invoke(nameof(RegisterSpawnerEvents), 0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterSpawnerEvents()
|
||||
{
|
||||
if (BasicSpawner.Instance == null) return;
|
||||
BasicSpawner.Instance.OnSessionListUpdatedEvent += UpdateRoomList;
|
||||
BasicSpawner.Instance.OnJoinFailedEvent += () => { if(_joinPassError != null) _joinPassError.style.display = DisplayStyle.Flex; };
|
||||
BasicSpawner.Instance.OnJoinStartedEvent += () => { /* Show loading if needed */ };
|
||||
}
|
||||
|
||||
public void SetRoomTemplate(VisualTreeAsset template) => _roomItemTemplate = template;
|
||||
@@ -110,38 +119,60 @@ namespace Hallucinate.UI
|
||||
|
||||
public void ShowJoin()
|
||||
{
|
||||
_joinContainer.style.display = DisplayStyle.Flex;
|
||||
_createContainer.style.display = DisplayStyle.None;
|
||||
_loungeContainer.style.display = DisplayStyle.None;
|
||||
_spawner?.StartLobby();
|
||||
if (_joinContainer != null) _joinContainer.style.display = DisplayStyle.Flex;
|
||||
if (_createContainer != null) _createContainer.style.display = DisplayStyle.None;
|
||||
if (_loungeContainer != null) _loungeContainer.style.display = DisplayStyle.None;
|
||||
BasicSpawner.Instance?.StartLobby();
|
||||
}
|
||||
|
||||
public void ShowCreate()
|
||||
{
|
||||
_joinContainer.style.display = DisplayStyle.None;
|
||||
_createContainer.style.display = DisplayStyle.Flex;
|
||||
if (_joinContainer != null) _joinContainer.style.display = DisplayStyle.None;
|
||||
if (_createContainer != null) _createContainer.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
|
||||
private void ShowLounge(string roomName)
|
||||
{
|
||||
_joinContainer.style.display = DisplayStyle.None;
|
||||
_createContainer.style.display = DisplayStyle.None;
|
||||
_loungeContainer.style.display = DisplayStyle.Flex;
|
||||
_loungeRoomName.text = $"Room: {roomName}";
|
||||
if (_joinContainer != null) _joinContainer.style.display = DisplayStyle.None;
|
||||
if (_createContainer != null) _createContainer.style.display = DisplayStyle.None;
|
||||
if (_loungeContainer != null) _loungeContainer.style.display = DisplayStyle.Flex;
|
||||
if (_loungeRoomName != null) _loungeRoomName.text = $"Room: {roomName}";
|
||||
|
||||
_playerDataManager = Object.FindFirstObjectByType<_PlayerDataManager>();
|
||||
_playerDataManager = Object.FindFirstObjectByType<PlayerDataManager>();
|
||||
}
|
||||
|
||||
private async void OnCreateRoomClicked()
|
||||
{
|
||||
string id = _roomIDInput.value.Trim();
|
||||
string name = string.IsNullOrEmpty(_roomNameInput.value) ? id : _roomNameInput.value;
|
||||
string pass = _passToggle.value ? _roomPassInput.value : null;
|
||||
var spawner = BasicSpawner.Instance;
|
||||
if (spawner == null)
|
||||
{
|
||||
Debug.LogError("[LobbyController] BasicSpawner.Instance is missing!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(id)) return;
|
||||
string id = _roomIDInput != null && !string.IsNullOrEmpty(_roomIDInput.value)
|
||||
? _roomIDInput.value.Trim()
|
||||
: Random.Range(1000, 9999).ToString();
|
||||
|
||||
await _spawner.StartHost(id, pass);
|
||||
ShowLounge(name);
|
||||
if (_roomIDInput != null) _roomIDInput.value = id;
|
||||
|
||||
string name = _roomNameInput != null && !string.IsNullOrEmpty(_roomNameInput.value)
|
||||
? _roomNameInput.value
|
||||
: $"Room {id}";
|
||||
|
||||
string pass = (_passToggle != null && _passToggle.value && _roomPassInput != null)
|
||||
? _roomPassInput.value
|
||||
: null;
|
||||
|
||||
bool success = await spawner.StartHost(id, pass);
|
||||
if (success)
|
||||
{
|
||||
ShowLounge(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[LobbyController] Failed to create room. Please check AppID/Region.");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateRoomList(List<SessionInfo> sessions)
|
||||
@@ -150,48 +181,53 @@ namespace Hallucinate.UI
|
||||
_roomList.Clear();
|
||||
foreach (var session in sessions)
|
||||
{
|
||||
if (_roomItemTemplate == null) continue;
|
||||
var item = _roomItemTemplate.Instantiate();
|
||||
item.Q<Label>("RoomName").text = session.Name;
|
||||
item.Q<Label>("PlayerCount").text = $"{session.PlayerCount}/{session.MaxPlayers}";
|
||||
|
||||
bool needsPass = session.Properties.ContainsKey("pw");
|
||||
item.Q<Label>("LockIcon").style.display = needsPass ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
var lockIcon = item.Q<Label>("LockIcon");
|
||||
if (lockIcon != null) lockIcon.style.display = needsPass ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
|
||||
var joinBtn = item.Q<Button>("JoinBtn");
|
||||
joinBtn.clicked += () => OnRoomItemClicked(session);
|
||||
if (joinBtn != null) joinBtn.clicked += () => OnRoomItemClicked(session);
|
||||
|
||||
_roomList.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRoomItemClicked(SessionInfo session)
|
||||
private async void OnRoomItemClicked(SessionInfo session)
|
||||
{
|
||||
bool needsPass = session.Properties.ContainsKey("pw");
|
||||
if (needsPass)
|
||||
{
|
||||
_selectedSession = session;
|
||||
_passOverlay.style.display = DisplayStyle.Flex;
|
||||
_joinPassError.style.display = DisplayStyle.None;
|
||||
_joinPassInput.value = "";
|
||||
if (_passOverlay != null) _passOverlay.style.display = DisplayStyle.Flex;
|
||||
if (_joinPassError != null) _joinPassError.style.display = DisplayStyle.None;
|
||||
if (_joinPassInput != null) _joinPassInput.value = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
JoinRoom(session.Name, null);
|
||||
await JoinRoom(session.Name, null);
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnConfirmPasswordClicked()
|
||||
{
|
||||
if (_selectedSession == null) return;
|
||||
string pass = _joinPassInput.value;
|
||||
_passOverlay.style.display = DisplayStyle.None;
|
||||
string pass = _joinPassInput != null ? _joinPassInput.value : "";
|
||||
if (_passOverlay != null) _passOverlay.style.display = DisplayStyle.None;
|
||||
await JoinRoom(_selectedSession.Name, pass);
|
||||
}
|
||||
|
||||
private async Task JoinRoom(string sessionName, string password)
|
||||
{
|
||||
await _spawner.StartClient(sessionName, password);
|
||||
ShowLounge(sessionName);
|
||||
if (BasicSpawner.Instance != null)
|
||||
{
|
||||
bool success = await BasicSpawner.Instance.StartClient(sessionName, password);
|
||||
if (success) ShowLounge(sessionName);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnReadyClicked()
|
||||
@@ -209,7 +245,7 @@ namespace Hallucinate.UI
|
||||
|
||||
private void OnStartClicked()
|
||||
{
|
||||
_spawner.StartGame();
|
||||
BasicSpawner.Instance?.StartGame();
|
||||
}
|
||||
|
||||
private void OnLeaveLoungeClicked()
|
||||
@@ -221,7 +257,7 @@ namespace Hallucinate.UI
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (_loungeContainer.style.display == DisplayStyle.Flex)
|
||||
if (_loungeContainer != null && _loungeContainer.style.display == DisplayStyle.Flex)
|
||||
{
|
||||
UpdateLoungeUI();
|
||||
}
|
||||
@@ -231,46 +267,55 @@ namespace Hallucinate.UI
|
||||
{
|
||||
if (_playerDataManager == null)
|
||||
{
|
||||
_playerDataManager = Object.FindFirstObjectByType<_PlayerDataManager>();
|
||||
_playerDataManager = Object.FindFirstObjectByType<PlayerDataManager>();
|
||||
return;
|
||||
}
|
||||
|
||||
var runner = Object.FindFirstObjectByType<NetworkRunner>();
|
||||
if (runner == null) return;
|
||||
|
||||
// Update Player List
|
||||
_playerListContainer.Clear();
|
||||
bool allReady = true;
|
||||
int playerCount = 0;
|
||||
|
||||
foreach (var kvp in _playerDataManager.Players)
|
||||
if (_playerListContainer != null)
|
||||
{
|
||||
playerCount++;
|
||||
var playerRef = kvp.Key;
|
||||
var data = kvp.Value;
|
||||
_playerListContainer.Clear();
|
||||
bool allReady = true;
|
||||
int playerCount = 0;
|
||||
|
||||
var playerItem = new VisualElement();
|
||||
playerItem.style.flexDirection = FlexDirection.Row;
|
||||
playerItem.style.justifyContent = Justify.SpaceBetween;
|
||||
playerItem.style.paddingBottom = 5;
|
||||
foreach (var kvp in _playerDataManager.Players)
|
||||
{
|
||||
playerCount++;
|
||||
var data = kvp.Value;
|
||||
|
||||
var nameLabel = new Label(data.Name.ToString());
|
||||
var readyLabel = new Label(data.IsReady ? "READY" : "WAITING...");
|
||||
readyLabel.style.color = data.IsReady ? Color.green : Color.yellow;
|
||||
var playerItem = new VisualElement();
|
||||
playerItem.style.flexDirection = FlexDirection.Row;
|
||||
playerItem.style.justifyContent = Justify.SpaceBetween;
|
||||
playerItem.style.paddingBottom = 5;
|
||||
|
||||
playerItem.Add(nameLabel);
|
||||
playerItem.Add(readyLabel);
|
||||
_playerListContainer.Add(playerItem);
|
||||
var nameLabel = new Label(data.Name.ToString());
|
||||
var readyLabel = new Label(data.IsReady ? "READY" : "WAITING...");
|
||||
readyLabel.style.color = data.IsReady ? Color.green : Color.yellow;
|
||||
|
||||
if (!data.IsReady) allReady = false;
|
||||
playerItem.Add(nameLabel);
|
||||
playerItem.Add(readyLabel);
|
||||
_playerListContainer.Add(playerItem);
|
||||
|
||||
if (!data.IsReady) allReady = false;
|
||||
}
|
||||
|
||||
if (_startBtn != null)
|
||||
_startBtn.style.display = (runner.IsServer && allReady && playerCount >= 2) ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
|
||||
if (_readyBtn != null)
|
||||
{
|
||||
_playerDataManager.TryGetPlayerMetaData(runner.LocalPlayer, out var myData);
|
||||
_readyBtn.text = myData.IsReady ? "UNREADY" : "READY UP";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update Buttons
|
||||
_startBtn.style.display = (runner.IsServer && allReady && playerCount >= 2) ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
|
||||
_playerDataManager.TryGetPlayerMetaData(runner.LocalPlayer, out var myData);
|
||||
_readyBtn.text = myData.IsReady ? "UNREADY" : "READY UP";
|
||||
private async void Invoke(string methodName, float delay)
|
||||
{
|
||||
await Task.Delay((int)(delay * 1000));
|
||||
if (methodName == nameof(RegisterSpawnerEvents)) RegisterSpawnerEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user