Update
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
#if false
|
||||
using System.Collections.Generic;
|
||||
using Fusion;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -96,4 +97,5 @@
|
||||
// tạo phòng mới với tên đã nhập
|
||||
await spawner.StartHost(roomName, SceneRef.FromIndex(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,296 +6,150 @@ using Fusion;
|
||||
using Fusion.Sockets;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
// ghi nhận các input của người chơi, ở đây chỉ có hướng di chuyển
|
||||
|
||||
|
||||
public class _BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
|
||||
namespace Hallucinate.UI
|
||||
{
|
||||
private NetworkRunner _runner { get; set; }
|
||||
public class _BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
|
||||
{
|
||||
private NetworkRunner _runner { get; set; }
|
||||
|
||||
public _LobbyManager LobbyManager;
|
||||
|
||||
public event Action<List<SessionInfo>> OnSessionListUpdatedEvent;
|
||||
public event Action<string> OnShutdownEvent;
|
||||
public event Action OnJoinStartedEvent;
|
||||
public event Action OnJoinFailedEvent;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (_runner == null) _runner = gameObject.AddComponent<NetworkRunner>();
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
|
||||
// dont destroy this object when loading new scenes
|
||||
if(_runner == null) _runner = gameObject.AddComponent<NetworkRunner>();
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
// thông tin profile của player local, sẽ được tạo ra từ lobby và gửi lên host để tạo player object, ở đây tạm thời chỉ tạo 1 profile mặc định
|
||||
public _PlayerProfile LocalPlayerProfile { get; private set; }
|
||||
public void SetLocalPlayerProfile(_PlayerProfile _profile)
|
||||
{
|
||||
LocalPlayerProfile = _profile;
|
||||
}
|
||||
|
||||
// start lobby
|
||||
public async Task StartLobby()
|
||||
{
|
||||
if(_runner == null) _runner = gameObject.AddComponent<NetworkRunner>();
|
||||
_runner.ProvideInput = true;
|
||||
_runner.AddCallbacks(this);
|
||||
var result = await _runner.JoinSessionLobby(SessionLobby.ClientServer);
|
||||
if (result.Ok)
|
||||
public _PlayerProfile LocalPlayerProfile { get; private set; }
|
||||
public void SetLocalPlayerProfile(_PlayerProfile _profile)
|
||||
{
|
||||
Debug.Log("Joined lobby successfully!");
|
||||
LocalPlayerProfile = _profile;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Failed to join lobby: {result.ShutdownReason}");
|
||||
}
|
||||
}
|
||||
|
||||
// tạo phòng
|
||||
public async Task StartHost(string sessionName, SceneRef scene)
|
||||
{
|
||||
var result = await _runner.StartGame(new StartGameArgs()
|
||||
{
|
||||
GameMode = GameMode.Host,
|
||||
SessionName = sessionName,
|
||||
Scene = scene,
|
||||
PlayerCount = 2,
|
||||
SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()
|
||||
});
|
||||
if (result.Ok)
|
||||
{
|
||||
Debug.Log("Started host successfully!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"Failed to start host: {result.ShutdownReason}");
|
||||
}
|
||||
}
|
||||
|
||||
// tham gia phòng
|
||||
public async Task StartClient(string sessionName)
|
||||
{
|
||||
var result = await _runner.StartGame(new StartGameArgs()
|
||||
{
|
||||
GameMode = GameMode.Client,
|
||||
SessionName = sessionName,
|
||||
SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()
|
||||
});
|
||||
if (result.Ok) {
|
||||
Debug.Log("Started client successfully!");
|
||||
}
|
||||
else {
|
||||
Debug.LogError($"Failed to start client: {result.ShutdownReason}");
|
||||
}
|
||||
}
|
||||
|
||||
public void OnObjectExitAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player)
|
||||
{
|
||||
|
||||
}
|
||||
public async Task StartLobby()
|
||||
{
|
||||
if (_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 void OnObjectEnterAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[SerializeField] private NetworkPrefabRef _playerPrefab;
|
||||
private Dictionary<PlayerRef, NetworkObject> _spawnedCharacters = new Dictionary<PlayerRef, NetworkObject>();
|
||||
public async Task StartHost(string sessionName, string password = null)
|
||||
{
|
||||
OnJoinStartedEvent?.Invoke();
|
||||
|
||||
public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
// nếu là host
|
||||
if (runner.IsServer)
|
||||
// Sử dụng SessionProperties để lưu mật khẩu
|
||||
var customProps = new Dictionary<string, SessionProperty>();
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
Vector2 spawnPosition;
|
||||
customProps.Add("pw", password);
|
||||
}
|
||||
|
||||
if (player == runner.LocalPlayer)
|
||||
{
|
||||
spawnPosition = new Vector2(-8, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnPosition = new Vector2(8, 0);
|
||||
}
|
||||
|
||||
|
||||
// Create a unique position for the player
|
||||
// var spawnPosition = new Vector2(Random.Range(0, 5), Random.Range(0, 5));
|
||||
var networkPlayerObject = runner.Spawn(
|
||||
_playerPrefab,
|
||||
spawnPosition,
|
||||
Quaternion.identity,
|
||||
player);
|
||||
// Keep track of the player avatars for easy access
|
||||
_spawnedCharacters.Add(player, networkPlayerObject);
|
||||
// if (runner.ActivePlayers.Count() == 2 && !_ballStarted)
|
||||
// {
|
||||
// var ball = FindFirstObjectByType<Ball>();
|
||||
// ball.Launch();
|
||||
// _ballStarted = true;
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
Debug.Log("Player joined: " + player + ", is local player: " + (player == runner.LocalPlayer));
|
||||
if (player == runner.LocalPlayer)
|
||||
{
|
||||
var pdm = FindFirstObjectByType<_PlayerDataManager>();
|
||||
if (pdm == null) return;
|
||||
var metaData = new _PlayerMetaData()
|
||||
var result = await _runner.StartGame(new StartGameArgs()
|
||||
{
|
||||
Name = LocalPlayerProfile.Name,
|
||||
Role = LocalPlayerProfile.Role,
|
||||
|
||||
};
|
||||
pdm.RPC_UpdatePlayerMetaData(player, metaData);
|
||||
}
|
||||
|
||||
}
|
||||
GameMode = GameMode.Host,
|
||||
SessionName = sessionName,
|
||||
SessionProperties = customProps,
|
||||
PlayerCount = 2,
|
||||
SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()
|
||||
});
|
||||
|
||||
public void OnPlayerLeft(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
if (_spawnedCharacters.TryGetValue(player, out NetworkObject networkObject))
|
||||
{
|
||||
runner.Despawn(networkObject);
|
||||
_spawnedCharacters.Remove(player);
|
||||
if (runner.IsServer)
|
||||
if (!result.Ok)
|
||||
{
|
||||
runner.Shutdown();
|
||||
Debug.LogError($"Failed to start host: {result.ShutdownReason}");
|
||||
OnJoinFailedEvent?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsGameReady(NetworkRunner runner)
|
||||
{
|
||||
|
||||
return runner.ActivePlayers.Count() >= 2;
|
||||
}
|
||||
|
||||
public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason)
|
||||
{
|
||||
Debug.Log("Game shutdown: " + shutdownReason);
|
||||
|
||||
|
||||
UnityEngine.SceneManagement.SceneManager.LoadScene("Lobby");
|
||||
}
|
||||
|
||||
public void OnDisconnectedFromServer(NetworkRunner runner, NetDisconnectReason reason)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnConnectRequest(NetworkRunner runner, NetworkRunnerCallbackArgs.ConnectRequest request, byte[] token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnConnectFailed(NetworkRunner runner, NetAddress remoteAddress, NetConnectFailedReason reason)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnUserSimulationMessage(NetworkRunner runner, SimulationMessagePtr message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnReliableDataReceived(NetworkRunner runner, PlayerRef player, ReliableKey key, ArraySegment<byte> data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnReliableDataProgress(NetworkRunner runner, PlayerRef player, ReliableKey key, float progress)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void OnInput(NetworkRunner runner, NetworkInput input)
|
||||
{
|
||||
// collect the input and send it to the runner, which will then be sent to the server and other clients
|
||||
var data = new _PlayerInputData();
|
||||
data.direction = Input.GetAxis("Vertical");
|
||||
input.Set(data);
|
||||
}
|
||||
|
||||
public void OnInputMissing(NetworkRunner runner, PlayerRef player, NetworkInput input)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnConnectedToServer(NetworkRunner runner)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// khi có update về danh sách phòng,
|
||||
// ví dụ khi có phòng mới được tạo hoặc phòng bị xóa,
|
||||
// host sẽ gửi update này cho tất cả client trong lobby
|
||||
public void OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList)
|
||||
{
|
||||
Debug.Log("Session list updated, total sessions: " + sessionList.Count);
|
||||
LobbyManager.DisplayRoomList(sessionList);
|
||||
}
|
||||
|
||||
public void OnCustomAuthenticationResponse(NetworkRunner runner, Dictionary<string, object> data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnHostMigration(NetworkRunner runner, HostMigrationToken hostMigrationToken)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnSceneLoadDone(NetworkRunner runner)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void OnSceneLoadStart(NetworkRunner runner)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void DespawnGO(NetworkObject networkObject)
|
||||
{
|
||||
if (_runner != null && networkObject != null)
|
||||
public async Task StartClient(string sessionName, string password = null)
|
||||
{
|
||||
_runner.Despawn(networkObject);
|
||||
}
|
||||
}
|
||||
OnJoinStartedEvent?.Invoke();
|
||||
|
||||
public NetworkObject SpawnGO(NetworkPrefabRef prefabRef, Vector2 position,Quaternion rotation, PlayerRef owner = default)
|
||||
{
|
||||
if (_runner != null)
|
||||
var result = await _runner.StartGame(new StartGameArgs()
|
||||
{
|
||||
GameMode = GameMode.Client,
|
||||
SessionName = sessionName,
|
||||
SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()
|
||||
});
|
||||
|
||||
if (!result.Ok)
|
||||
{
|
||||
Debug.LogError($"Failed to join client: {result.ShutdownReason}");
|
||||
OnJoinFailedEvent?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private NetworkPrefabRef _playerPrefab;
|
||||
private Dictionary<PlayerRef, NetworkObject> _spawnedCharacters = new Dictionary<PlayerRef, NetworkObject>();
|
||||
|
||||
public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
return _runner.Spawn(prefabRef, position, rotation, owner);
|
||||
if (runner.IsServer)
|
||||
{
|
||||
Vector2 spawnPosition = (player == runner.LocalPlayer) ? new Vector2(-8, 0) : new Vector2(8, 0);
|
||||
var networkPlayerObject = runner.Spawn(_playerPrefab, spawnPosition, Quaternion.identity, player);
|
||||
_spawnedCharacters.Add(player, networkPlayerObject);
|
||||
}
|
||||
|
||||
if (player == runner.LocalPlayer)
|
||||
{
|
||||
var pdm = FindFirstObjectByType<_PlayerDataManager>();
|
||||
if (pdm != null)
|
||||
{
|
||||
var metaData = new _PlayerMetaData()
|
||||
{
|
||||
Name = LocalPlayerProfile.Name,
|
||||
Role = LocalPlayerProfile.Role,
|
||||
};
|
||||
pdm.RPC_UpdatePlayerMetaData(player, metaData);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
void AssignRoles(NetworkRunner runner)
|
||||
{
|
||||
var players = runner.ActivePlayers.ToList();
|
||||
|
||||
if (players.Count < 2) return;
|
||||
public void OnPlayerLeft(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
if (_spawnedCharacters.TryGetValue(player, out NetworkObject networkObject))
|
||||
{
|
||||
runner.Despawn(networkObject);
|
||||
_spawnedCharacters.Remove(player);
|
||||
if (runner.IsServer) runner.Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
var p1 = players[0];
|
||||
var p2 = players[1];
|
||||
public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason)
|
||||
{
|
||||
OnShutdownEvent?.Invoke(shutdownReason.ToString());
|
||||
}
|
||||
|
||||
bool random = UnityEngine.Random.value > 0.5f;
|
||||
public void OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList)
|
||||
{
|
||||
OnSessionListUpdatedEvent?.Invoke(sessionList);
|
||||
}
|
||||
|
||||
SetRole(runner, p1, random ? _Role.Seeker : _Role.Trapper);
|
||||
SetRole(runner, p2, random ? _Role.Trapper : _Role.Seeker);
|
||||
}
|
||||
void SetRole(NetworkRunner runner, PlayerRef player, _Role role)
|
||||
{
|
||||
var obj = runner.GetPlayerObject(player);
|
||||
var data = obj.GetComponent<_PlayerData>();
|
||||
public void OnInput(NetworkRunner runner, NetworkInput input)
|
||||
{
|
||||
var data = new _PlayerInputData();
|
||||
data.direction = Input.GetAxis("Vertical");
|
||||
input.Set(data);
|
||||
}
|
||||
|
||||
data.PlayerRole = role;
|
||||
|
||||
Debug.Log($"Player {player} assigned role: {role}");
|
||||
public void OnConnectedToServer(NetworkRunner runner) { }
|
||||
public void OnDisconnectedFromServer(NetworkRunner runner, NetDisconnectReason reason) { }
|
||||
public void OnConnectRequest(NetworkRunner runner, NetworkRunnerCallbackArgs.ConnectRequest request, byte[] token) { }
|
||||
public void OnConnectFailed(NetworkRunner runner, NetAddress remoteAddress, NetConnectFailedReason reason) { }
|
||||
public void OnUserSimulationMessage(NetworkRunner runner, SimulationMessagePtr message) { }
|
||||
public void OnReliableDataReceived(NetworkRunner runner, PlayerRef player, ReliableKey key, ArraySegment<byte> data) { }
|
||||
public void OnReliableDataProgress(NetworkRunner runner, PlayerRef player, ReliableKey key, float progress) { }
|
||||
public void OnInputMissing(NetworkRunner runner, PlayerRef player, NetworkInput input) { }
|
||||
public void OnObjectExitAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player) { }
|
||||
public void OnObjectEnterAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player) { }
|
||||
public void OnCustomAuthenticationResponse(NetworkRunner runner, Dictionary<string, object> data) { }
|
||||
public void OnHostMigration(NetworkRunner runner, HostMigrationToken hostMigrationToken) { }
|
||||
public void OnSceneLoadDone(NetworkRunner runner) { }
|
||||
public void OnSceneLoadStart(NetworkRunner runner) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +1,129 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Fusion;
|
||||
|
||||
namespace Hallucinate.UI
|
||||
{
|
||||
public class LobbyController : BaseUIController
|
||||
{
|
||||
private VisualElement _joinContainer;
|
||||
private VisualElement _createContainer;
|
||||
private VisualElement _loungeContainer;
|
||||
private VisualTreeAsset _roomItemTemplate;
|
||||
private _BasicSpawner _spawner;
|
||||
|
||||
private Button _backBtn;
|
||||
private Button _createFinalBtn;
|
||||
private Button _startGameBtn;
|
||||
|
||||
private Toggle _hostReady;
|
||||
private Toggle _guestReady;
|
||||
// Containers
|
||||
private VisualElement _joinContainer, _createContainer, _loungeContainer, _passOverlay;
|
||||
|
||||
// Create Room Fields
|
||||
private TextField _roomIDInput, _roomNameInput, _roomPassInput;
|
||||
private Toggle _passToggle;
|
||||
|
||||
// Join Room Fields
|
||||
private ScrollView _roomList;
|
||||
private TextField _joinPassInput;
|
||||
private Label _joinPassError;
|
||||
private SessionInfo _selectedSession;
|
||||
|
||||
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
|
||||
{
|
||||
base.Initialize(uxmlRoot, manager);
|
||||
_spawner = Object.FindFirstObjectByType<_BasicSpawner>();
|
||||
|
||||
// Query Elements
|
||||
_joinContainer = root.Q<VisualElement>("JoinContainer");
|
||||
_createContainer = root.Q<VisualElement>("CreateContainer");
|
||||
_loungeContainer = root.Q<VisualElement>("LoungeContainer");
|
||||
_passOverlay = root.Q<VisualElement>("PasswordOverlay");
|
||||
|
||||
_backBtn = root.Q<Button>("BackToMenuBtn");
|
||||
_createFinalBtn = root.Q<Button>("CreateRoomFinalBtn");
|
||||
_startGameBtn = root.Q<Button>("StartGameBtn");
|
||||
|
||||
_hostReady = root.Q<Toggle>("HostReady");
|
||||
_guestReady = root.Q<Toggle>("GuestReady");
|
||||
|
||||
_backBtn.clicked += () => uiManager.Pop();
|
||||
_createFinalBtn.clicked += () => ShowLounge();
|
||||
_roomIDInput = root.Q<TextField>("RoomIDInput");
|
||||
_roomNameInput = root.Q<TextField>("RoomNameInput");
|
||||
_roomPassInput = root.Q<TextField>("RoomPassInput");
|
||||
_passToggle = root.Q<Toggle>("PassToggle");
|
||||
_roomList = root.Q<ScrollView>("RoomList");
|
||||
|
||||
_hostReady.RegisterValueChangedCallback(evt => UpdateStartButton());
|
||||
_guestReady.RegisterValueChangedCallback(evt => UpdateStartButton());
|
||||
_joinPassInput = root.Q<TextField>("JoinPassInput");
|
||||
_joinPassError = root.Q<Label>("JoinPassError");
|
||||
|
||||
UpdateStartButton();
|
||||
// Event Bindings
|
||||
root.Q<Button>("GoToCreateBtn").clicked += ShowCreate;
|
||||
root.Q<Button>("CancelCreateBtn").clicked += ShowJoin;
|
||||
root.Q<Button>("BackToMenuBtn").clicked += () => uiManager.Pop();
|
||||
root.Q<Button>("ConfirmCreateBtn").clicked += OnCreateRoomClicked;
|
||||
root.Q<Button>("ConfirmJoinBtn").clicked += OnConfirmPasswordClicked;
|
||||
root.Q<Button>("ClosePassBtn").clicked += () => _passOverlay.style.display = DisplayStyle.None;
|
||||
|
||||
_passToggle.RegisterValueChangedCallback(evt =>
|
||||
_roomPassInput.style.display = evt.newValue ? DisplayStyle.Flex : DisplayStyle.None);
|
||||
|
||||
// Đăng ký sự kiện từ Spawner
|
||||
if (_spawner != null)
|
||||
{
|
||||
_spawner.OnSessionListUpdatedEvent += UpdateRoomList;
|
||||
_spawner.OnJoinFailedEvent += () => _joinPassError.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetRoomTemplate(VisualTreeAsset template) => _roomItemTemplate = template;
|
||||
|
||||
public void ShowJoin()
|
||||
{
|
||||
_joinContainer.style.display = DisplayStyle.Flex;
|
||||
_createContainer.style.display = DisplayStyle.None;
|
||||
_loungeContainer.style.display = DisplayStyle.None;
|
||||
_spawner?.StartLobby();
|
||||
}
|
||||
|
||||
public void ShowCreate()
|
||||
{
|
||||
_joinContainer.style.display = DisplayStyle.None;
|
||||
_createContainer.style.display = DisplayStyle.Flex;
|
||||
_loungeContainer.style.display = DisplayStyle.None;
|
||||
}
|
||||
|
||||
public void ShowLounge()
|
||||
private async void OnCreateRoomClicked()
|
||||
{
|
||||
_joinContainer.style.display = DisplayStyle.None;
|
||||
_createContainer.style.display = DisplayStyle.None;
|
||||
_loungeContainer.style.display = DisplayStyle.Flex;
|
||||
string id = _roomIDInput.value.Trim();
|
||||
string name = string.IsNullOrEmpty(_roomNameInput.value) ? id : _roomNameInput.value;
|
||||
string pass = _passToggle.value ? _roomPassInput.value : null;
|
||||
|
||||
if (string.IsNullOrEmpty(id)) return;
|
||||
|
||||
await _spawner.StartHost(id, pass);
|
||||
// Logic chuyển sang Lounge sẽ được xử lý qua sự kiện OnPlayerJoined trong Spawner
|
||||
}
|
||||
|
||||
private void UpdateStartButton()
|
||||
private void UpdateRoomList(List<SessionInfo> sessions)
|
||||
{
|
||||
if (_startGameBtn != null)
|
||||
_roomList.Clear();
|
||||
foreach (var session in sessions)
|
||||
{
|
||||
_startGameBtn.SetEnabled(_hostReady.value && _guestReady.value);
|
||||
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"); // Giả sử dùng metadata
|
||||
item.Q<Label>("LockIcon").style.display = needsPass ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
|
||||
var joinBtn = item.Q<Button>("JoinBtn");
|
||||
joinBtn.clicked += () => OnRoomItemClicked(session);
|
||||
|
||||
_roomList.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRoomItemClicked(SessionInfo session)
|
||||
{
|
||||
_selectedSession = session;
|
||||
// Fusion dùng Password trong StartGameArgs, nên ta hiện popup nhập trước
|
||||
_passOverlay.style.display = DisplayStyle.Flex;
|
||||
_joinPassError.style.display = DisplayStyle.None;
|
||||
_joinPassInput.value = "";
|
||||
}
|
||||
|
||||
private async void OnConfirmPasswordClicked()
|
||||
{
|
||||
if (_selectedSession == null) return;
|
||||
string pass = _joinPassInput.value;
|
||||
await _spawner.StartClient(_selectedSession.Name, pass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,15 +40,17 @@ namespace Hallucinate.UI
|
||||
[SerializeField] private Color rippleColor = new Color(1, 1, 1, 0.4f);
|
||||
|
||||
[Header("UI Templates")]
|
||||
[SerializeField] private VisualTreeAsset loginTemplate; // Template mới
|
||||
[SerializeField] private VisualTreeAsset loginTemplate;
|
||||
[SerializeField] private VisualTreeAsset mainMenuTemplate;
|
||||
[SerializeField] private VisualTreeAsset lobbyTemplate;
|
||||
[SerializeField] private VisualTreeAsset roomItemTemplate; // Template cho dòng phòng
|
||||
[SerializeField] private VisualTreeAsset profileTemplate;
|
||||
[SerializeField] private VisualTreeAsset settingsTemplate;
|
||||
[SerializeField] private VisualTreeAsset hudTemplate;
|
||||
|
||||
private LoginController _loginController;
|
||||
private MainMenuController _mainMenuController;
|
||||
private LobbyController _lobbyController;
|
||||
private SettingsController _settingsController;
|
||||
private List<VisualElement> _trailSegments = new List<VisualElement>();
|
||||
private List<Vector2> _posHistory = new List<Vector2>();
|
||||
@@ -95,8 +97,6 @@ namespace Hallucinate.UI
|
||||
}
|
||||
#endif
|
||||
InitializeControllers();
|
||||
|
||||
// KIỂM TRA LOGIN
|
||||
CheckLoginStatus();
|
||||
}
|
||||
|
||||
@@ -116,7 +116,6 @@ namespace Hallucinate.UI
|
||||
|
||||
public void OnLoginSuccess()
|
||||
{
|
||||
// Sau khi login xong thì hiện MainMenu
|
||||
_ = Push<MainMenuController>();
|
||||
}
|
||||
|
||||
@@ -286,14 +285,17 @@ namespace Hallucinate.UI
|
||||
|
||||
private void InitializeControllers()
|
||||
{
|
||||
_loginController = RegisterController<LoginController>(loginTemplate);
|
||||
_mainMenuController = RegisterController<MainMenuController>(mainMenuTemplate);
|
||||
if (_mainMenuController != null && gameIcon != null) _mainMenuController.SetGameIcon(gameIcon);
|
||||
|
||||
RegisterController<LobbyController>(lobbyTemplate);
|
||||
_lobbyController = RegisterController<LobbyController>(lobbyTemplate);
|
||||
if (_lobbyController != null) _lobbyController.SetRoomTemplate(roomItemTemplate);
|
||||
|
||||
RegisterController<ProfileController>(profileTemplate);
|
||||
_settingsController = RegisterController<SettingsController>(settingsTemplate);
|
||||
RegisterController<HUDController>(hudTemplate);
|
||||
|
||||
_loginController = RegisterController<LoginController>(loginTemplate);
|
||||
}
|
||||
|
||||
private T RegisterController<T>(VisualTreeAsset template) where T : BaseUIController, new()
|
||||
|
||||
Reference in New Issue
Block a user