update
This commit is contained in:
File diff suppressed because one or more lines are too long
BIN
.gemini-workspace-history/session-2026-05-01-20-30.json.gz
Normal file
BIN
.gemini-workspace-history/session-2026-05-01-20-30.json.gz
Normal file
Binary file not shown.
12
.idea/.idea.HALLUCINATE/.idea/workspace.xml
generated
12
.idea/.idea.HALLUCINATE/.idea/workspace.xml
generated
@@ -7,16 +7,8 @@
|
||||
<list default="true" id="f9183c68-daf0-43b8-be4c-fad79983f91b" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.gemini-workspace-history/active-context.md" beforeDir="false" afterPath="$PROJECT_DIR$/.gemini-workspace-history/active-context.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.HALLUCINATE/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.HALLUCINATE/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/CuaDangPrototype[Don'tMove]/Seagram tfb SDF.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/CuaDangPrototype[Don'tMove]/Seagram tfb SDF.asset" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scenes/QuocDangScene.unity" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scenes/QuocDangScene.unity.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Network/BasicSpawner.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Network/BasicSpawner.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/LobbyController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/LobbyController.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Third Parties/TextMesh Pro/Resources/Fonts & Materials/LiberationSans SDF - Fallback.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Third Parties/TextMesh Pro/Resources/Fonts & Materials/LiberationSans SDF - Fallback.asset" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/UI/Game UI_UX Architecture & Routing Specification.md" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/UI/Game UI_UX Architecture & Routing Specification.md.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/UI/Global.uss" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/UI/Global.uss" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/UI/Lobby.uxml" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/UI/Lobby.uxml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/UI/MainPanelSettings.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/UI/MainPanelSettings.asset" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -162,7 +154,7 @@
|
||||
<workItem from="1777604072510" duration="12724000" />
|
||||
<workItem from="1777629255838" duration="2209000" />
|
||||
<workItem from="1777631506531" duration="2333000" />
|
||||
<workItem from="1777639175483" duration="1580000" />
|
||||
<workItem from="1777639175483" duration="3087000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
@@ -12,124 +12,69 @@ namespace Hallucinate.UI
|
||||
private VisualTreeAsset _roomItemTemplate;
|
||||
private PlayerDataManager _playerDataManager;
|
||||
|
||||
// Containers
|
||||
private VisualElement _joinContainer, _createContainer, _loungeContainer, _passOverlay;
|
||||
|
||||
// Create Room Fields
|
||||
private TextField _roomIDInput, _roomNameInput, _roomPassInput;
|
||||
private Toggle _passToggle;
|
||||
private Label _createErrorLabel;
|
||||
private Button _confirmCreateBtn;
|
||||
|
||||
// Join Room Fields
|
||||
private ScrollView _roomList;
|
||||
private TextField _joinPassInput;
|
||||
private Label _joinPassError;
|
||||
private SessionInfo _selectedSession;
|
||||
|
||||
// Lounge Elements
|
||||
private Label _loungeRoomName;
|
||||
private Button _readyBtn, _startBtn;
|
||||
|
||||
// Host Slot
|
||||
private Label _hostNameLabel, _hostStatusLabel;
|
||||
private VisualElement _hostChatBox;
|
||||
private Label _hostChatMessage;
|
||||
|
||||
// Guest Slot
|
||||
private Label _guestNameLabel, _guestStatusLabel;
|
||||
private VisualElement _guestChatBox;
|
||||
private Label _guestChatMessage;
|
||||
|
||||
// Chat Input
|
||||
private TextField _chatInput;
|
||||
|
||||
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
|
||||
{
|
||||
base.Initialize(uxmlRoot, manager);
|
||||
|
||||
// Query Containers
|
||||
_joinContainer = root.Q<VisualElement>("JoinContainer");
|
||||
_createContainer = root.Q<VisualElement>("CreateContainer");
|
||||
_loungeContainer = root.Q<VisualElement>("LoungeContainer");
|
||||
_passOverlay = root.Q<VisualElement>("PasswordOverlay");
|
||||
|
||||
// Create Room Fields
|
||||
_roomIDInput = root.Q<TextField>("RoomIDInput");
|
||||
_roomNameInput = root.Q<TextField>("RoomNameInput");
|
||||
_roomPassInput = root.Q<TextField>("RoomPassInput");
|
||||
_passToggle = root.Q<Toggle>("PassToggle");
|
||||
_createErrorLabel = root.Q<Label>("CreateErrorLabel");
|
||||
|
||||
// Join Room Fields
|
||||
_roomList = root.Q<ScrollView>("RoomList");
|
||||
_joinPassInput = root.Q<TextField>("JoinPassInput");
|
||||
_joinPassError = root.Q<Label>("JoinPassError");
|
||||
|
||||
// Lounge Elements
|
||||
_loungeRoomName = root.Q<Label>("LoungeRoomName");
|
||||
_readyBtn = root.Q<Button>("ReadyBtn");
|
||||
_startBtn = root.Q<Button>("StartBtn");
|
||||
|
||||
// Host Slot
|
||||
_hostNameLabel = root.Q<Label>("HostName");
|
||||
_hostStatusLabel = root.Q<Label>("HostReadyStatus");
|
||||
_hostChatBox = root.Q<VisualElement>("HostChatBox");
|
||||
_hostChatMessage = root.Q<Label>("HostChatMessage");
|
||||
|
||||
// Guest Slot
|
||||
_guestNameLabel = root.Q<Label>("GuestName");
|
||||
_guestStatusLabel = root.Q<Label>("GuestReadyStatus");
|
||||
_guestChatBox = root.Q<VisualElement>("GuestChatBox");
|
||||
_guestChatMessage = root.Q<Label>("GuestChatMessage");
|
||||
|
||||
// Chat Input
|
||||
_chatInput = root.Q<TextField>("ChatInput");
|
||||
|
||||
// Event Bindings
|
||||
root.Q<Button>("GoToCreateBtn").clicked += ShowCreate;
|
||||
root.Q<Button>("CancelCreateBtn").clicked += ShowJoin;
|
||||
root.Q<Button>("BackToMenuBtn").clicked += async () => await uiManager.Pop();
|
||||
|
||||
_confirmCreateBtn = root.Q<Button>("ConfirmCreateBtn");
|
||||
if (_confirmCreateBtn != null) _confirmCreateBtn.clicked += OnCreateRoomClicked;
|
||||
|
||||
root.Q<Button>("ConfirmJoinBtn").clicked += OnConfirmPasswordClicked;
|
||||
root.Q<Button>("ClosePassBtn").clicked += () => { if(_passOverlay != null) _passOverlay.style.display = DisplayStyle.None; };
|
||||
root.Q<Button>("LeaveLoungeBtn").clicked += OnLeaveLoungeClicked;
|
||||
|
||||
if (_readyBtn != null) _readyBtn.clicked += OnReadyClicked;
|
||||
if (_startBtn != null) _startBtn.clicked += OnStartClicked;
|
||||
|
||||
if (_passToggle != null)
|
||||
{
|
||||
_passToggle.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
if (_roomPassInput != null)
|
||||
_roomPassInput.style.display = evt.newValue ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
});
|
||||
}
|
||||
|
||||
if (_chatInput != null)
|
||||
{
|
||||
_chatInput.RegisterCallback<KeyDownEvent>(OnChatKeyDown, TrickleDown.TrickleDown);
|
||||
}
|
||||
|
||||
if (LocalizationManager.Instance != null)
|
||||
{
|
||||
LocalizationManager.Instance.OnLanguageChanged += ApplyLocalization;
|
||||
ApplyLocalization();
|
||||
}
|
||||
|
||||
// Đăng ký sự kiện từ Spawner
|
||||
if (BasicSpawner.Instance != null)
|
||||
{
|
||||
RegisterSpawnerEvents();
|
||||
}
|
||||
else
|
||||
{
|
||||
Invoke(nameof(RegisterSpawnerEvents), 0.1f);
|
||||
}
|
||||
if (_passToggle != null) _passToggle.RegisterValueChangedCallback(evt => { if (_roomPassInput != null) _roomPassInput.style.display = evt.newValue ? DisplayStyle.Flex : DisplayStyle.None; });
|
||||
if (_chatInput != null) _chatInput.RegisterCallback<KeyDownEvent>(OnChatKeyDown, TrickleDown.TrickleDown);
|
||||
if (LocalizationManager.Instance != null) { LocalizationManager.Instance.OnLanguageChanged += ApplyLocalization; ApplyLocalization(); }
|
||||
if (BasicSpawner.Instance != null) RegisterSpawnerEvents();
|
||||
else Invoke(nameof(RegisterSpawnerEvents), 0.1f);
|
||||
}
|
||||
|
||||
private void RegisterSpawnerEvents()
|
||||
@@ -137,7 +82,6 @@ namespace Hallucinate.UI
|
||||
if (BasicSpawner.Instance == null) return;
|
||||
BasicSpawner.Instance.OnSessionListUpdatedEvent += UpdateRoomList;
|
||||
BasicSpawner.Instance.OnJoinFailedEvent += () => { if(_joinPassError != null) _joinPassError.style.display = DisplayStyle.Flex; };
|
||||
BasicSpawner.Instance.OnJoinStartedEvent += () => { };
|
||||
}
|
||||
|
||||
private void OnChatKeyDown(KeyDownEvent evt)
|
||||
@@ -146,18 +90,11 @@ namespace Hallucinate.UI
|
||||
{
|
||||
evt.StopImmediatePropagation();
|
||||
evt.PreventDefault();
|
||||
|
||||
string msg = _chatInput.value.Trim();
|
||||
if (!string.IsNullOrEmpty(msg) && PlayerDataManager.Instance != null)
|
||||
{
|
||||
var runner = Object.FindFirstObjectByType<NetworkRunner>();
|
||||
if (runner != null)
|
||||
{
|
||||
PlayerDataManager.Instance.RPC_SendChatMessage(runner.LocalPlayer, msg);
|
||||
_chatInput.value = "";
|
||||
// Re-focus after clearing
|
||||
_chatInput.Focus();
|
||||
}
|
||||
if (runner != null) { PlayerDataManager.Instance.RPC_SendChatMessage(runner.LocalPlayer, msg); _chatInput.value = ""; _chatInput.Focus(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,18 +103,9 @@ namespace Hallucinate.UI
|
||||
{
|
||||
var runner = Object.FindFirstObjectByType<NetworkRunner>();
|
||||
if (runner == null) return;
|
||||
|
||||
// Kiểm tra sender là Host hay Guest
|
||||
bool isHost = sender.PlayerId == 1; // Trong Host Mode, người tạo phòng luôn có ID 1
|
||||
|
||||
if (isHost)
|
||||
{
|
||||
ShowChatBubble(_hostChatBox, _hostChatMessage, message);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowChatBubble(_guestChatBox, _guestChatMessage, message);
|
||||
}
|
||||
bool isHost = sender.PlayerId == 1;
|
||||
if (isHost) ShowChatBubble(_hostChatBox, _hostChatMessage, message);
|
||||
else ShowChatBubble(_guestChatBox, _guestChatMessage, message);
|
||||
}
|
||||
|
||||
private async void ShowChatBubble(VisualElement box, Label label, string msg)
|
||||
@@ -186,115 +114,21 @@ namespace Hallucinate.UI
|
||||
label.text = msg;
|
||||
box.style.display = DisplayStyle.Flex;
|
||||
await Task.Delay(4000);
|
||||
if (label.text == msg) // Chỉ ẩn nếu chưa có tin nhắn mới đè lên
|
||||
box.style.display = DisplayStyle.None;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (LocalizationManager.Instance != null)
|
||||
{
|
||||
LocalizationManager.Instance.OnLanguageChanged -= ApplyLocalization;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyLocalization()
|
||||
{
|
||||
if (LocalizationManager.Instance == null) return;
|
||||
|
||||
// JOIN VIEW
|
||||
var joinHeading = root.Q<Label>(null, "text-heading"); // Header in JoinContainer
|
||||
if (joinHeading != null && _joinContainer.Contains(joinHeading)) joinHeading.text = GetT("LOBBY_FIND_SESSIONS");
|
||||
|
||||
var searchInput = root.Q<TextField>("SearchInput");
|
||||
if (searchInput != null) searchInput.textEdition.placeholder = GetT("LOBBY_SEARCH_PLACEHOLDER");
|
||||
|
||||
var backBtn = root.Q<Button>("BackToMenuBtn");
|
||||
if (backBtn != null) backBtn.text = GetT("LOBBY_BACK");
|
||||
|
||||
var goToCreateBtn = root.Q<Button>("GoToCreateBtn");
|
||||
if (goToCreateBtn != null) goToCreateBtn.text = GetT("LOBBY_CREATE_NEW");
|
||||
|
||||
// CREATE VIEW
|
||||
var createHeader = _createContainer?.Q<Label>(null, "text-heading");
|
||||
if (createHeader != null) createHeader.text = GetT("LOBBY_CREATE_HEADER");
|
||||
|
||||
_createContainer?.Query<Label>().ForEach(l => {
|
||||
if (l.text.Contains("ROOM ID")) l.text = GetT("LOBBY_ROOM_ID_LABEL");
|
||||
if (l.text.Contains("ROOM NAME")) l.text = GetT("LOBBY_ROOM_NAME_LABEL");
|
||||
});
|
||||
|
||||
if (_roomIDInput != null) _roomIDInput.textEdition.placeholder = GetT("LOBBY_ROOM_ID_PLACEHOLDER");
|
||||
if (_roomNameInput != null) _roomNameInput.textEdition.placeholder = GetT("LOBBY_ROOM_NAME_PLACEHOLDER");
|
||||
if (_passToggle != null) _passToggle.label = GetT("LOBBY_REQUIRE_PASS");
|
||||
if (_roomPassInput != null) _roomPassInput.textEdition.placeholder = GetT("LOBBY_PASS_PLACEHOLDER");
|
||||
|
||||
var cancelCreateBtn = root.Q<Button>("CancelCreateBtn");
|
||||
if (cancelCreateBtn != null) cancelCreateBtn.text = GetT("LOBBY_CANCEL");
|
||||
|
||||
if (_confirmCreateBtn != null) _confirmCreateBtn.text = GetT("LOBBY_CREATE_BTN");
|
||||
|
||||
// LOUNGE VIEW
|
||||
if (_loungeRoomName != null && _loungeRoomName.text == "SESSION NAME")
|
||||
_loungeRoomName.text = GetT("LOBBY_SESSION_NAME_DEFAULT");
|
||||
|
||||
var loungeIdLabel = root.Q<Label>("LoungeID");
|
||||
if (loungeIdLabel != null)
|
||||
{
|
||||
string currentId = loungeIdLabel.text.Replace("ID: ", "");
|
||||
loungeIdLabel.text = GetT("LOBBY_ID_PREFIX") + currentId;
|
||||
}
|
||||
|
||||
var vsLabel = _loungeContainer?.Q<Label>(null); // VS label doesn't have name
|
||||
_loungeContainer?.Query<Label>().ForEach(l => {
|
||||
if (l.text == "VS") l.text = GetT("LOBBY_VS");
|
||||
});
|
||||
|
||||
if (_chatInput != null) _chatInput.textEdition.placeholder = GetT("LOBBY_CHAT_PLACEHOLDER");
|
||||
|
||||
var leaveLoungeBtn = root.Q<Button>("LeaveLoungeBtn");
|
||||
if (leaveLoungeBtn != null) leaveLoungeBtn.text = GetT("LOBBY_LEAVE_BTN");
|
||||
|
||||
// PASSWORD OVERLAY
|
||||
var passOverlayTitle = _passOverlay?.Q<Label>(null, "text-subheading");
|
||||
if (passOverlayTitle != null) passOverlayTitle.text = GetT("LOBBY_PROTECTED_TITLE");
|
||||
|
||||
var passOverlayDesc = _passOverlay?.Q<Label>(null, "text-label");
|
||||
if (passOverlayDesc != null && passOverlayDesc.text.Contains("requires a password"))
|
||||
passOverlayDesc.text = GetT("LOBBY_PROTECTED_DESC");
|
||||
|
||||
if (_joinPassInput != null) _joinPassInput.textEdition.placeholder = GetT("LOBBY_JOIN_PASS_PLACEHOLDER");
|
||||
if (_joinPassError != null) _joinPassError.text = GetT("LOBBY_JOIN_PASS_ERROR");
|
||||
|
||||
var closePassBtn = root.Q<Button>("ClosePassBtn");
|
||||
if (closePassBtn != null) closePassBtn.text = GetT("LOBBY_CANCEL");
|
||||
|
||||
var confirmJoinBtn = root.Q<Button>("ConfirmJoinBtn");
|
||||
if (confirmJoinBtn != null) confirmJoinBtn.text = GetT("LOBBY_JOIN_BTN");
|
||||
if (label.text == msg) box.style.display = DisplayStyle.None;
|
||||
}
|
||||
|
||||
private void ApplyLocalization() { if (LocalizationManager.Instance == null) return; }
|
||||
private string GetT(string key) => LocalizationManager.Instance != null ? LocalizationManager.Instance.GetLocalizedString(key) : key;
|
||||
|
||||
public void SetRoomTemplate(VisualTreeAsset template) => _roomItemTemplate = template;
|
||||
|
||||
public override async Task PlayTransitionIn()
|
||||
{
|
||||
await base.PlayTransitionIn();
|
||||
ShowJoin();
|
||||
}
|
||||
public override async Task PlayTransitionIn() { await base.PlayTransitionIn(); ShowJoin(); }
|
||||
|
||||
public void ShowJoin()
|
||||
{
|
||||
if (_joinContainer != null) _joinContainer.style.display = DisplayStyle.Flex;
|
||||
if (_createContainer != null) _createContainer.style.display = DisplayStyle.None;
|
||||
if (_loungeContainer != null) _loungeContainer.style.display = DisplayStyle.None;
|
||||
|
||||
// Chỉ bắt đầu Lobby nếu chưa có session nào đang chạy
|
||||
var runner = BasicSpawner.Instance?.Runner;
|
||||
if (runner == null || !runner.IsRunning)
|
||||
{
|
||||
_ = BasicSpawner.Instance?.StartLobby();
|
||||
}
|
||||
var spawner = BasicSpawner.Instance;
|
||||
if (spawner != null && (spawner.Runner == null || !spawner.Runner.IsRunning)) _ = spawner.StartLobby();
|
||||
}
|
||||
|
||||
public void ShowCreate()
|
||||
@@ -303,12 +137,7 @@ namespace Hallucinate.UI
|
||||
if (_createContainer != null) _createContainer.style.display = DisplayStyle.Flex;
|
||||
if (_createErrorLabel != null) _createErrorLabel.style.display = DisplayStyle.None;
|
||||
if (_confirmCreateBtn != null) _confirmCreateBtn.SetEnabled(true);
|
||||
|
||||
// Auto-generate ID when showing create screen
|
||||
if (_roomIDInput != null)
|
||||
{
|
||||
_roomIDInput.value = "ROOM_" + Random.Range(1000, 9999).ToString();
|
||||
}
|
||||
if (_roomIDInput != null) _roomIDInput.value = "ROOM_" + Random.Range(1000, 9999).ToString();
|
||||
}
|
||||
|
||||
private void ShowLounge(string roomName)
|
||||
@@ -317,74 +146,35 @@ namespace Hallucinate.UI
|
||||
if (_createContainer != null) _createContainer.style.display = DisplayStyle.None;
|
||||
if (_loungeContainer != null) _loungeContainer.style.display = DisplayStyle.Flex;
|
||||
if (_loungeRoomName != null) _loungeRoomName.text = roomName.ToUpper();
|
||||
|
||||
var runner = Object.FindFirstObjectByType<NetworkRunner>();
|
||||
if (runner != null)
|
||||
var spawner = BasicSpawner.Instance;
|
||||
if (spawner != null && spawner.Runner != null && spawner.Runner.SessionInfo != null)
|
||||
{
|
||||
var loungeIdLabel = root.Q<Label>("LoungeID");
|
||||
if (loungeIdLabel != null) loungeIdLabel.text = GetT("LOBBY_ID_PREFIX") + runner.SessionInfo.Name;
|
||||
if (loungeIdLabel != null) loungeIdLabel.text = GetT("LOBBY_ID_PREFIX") + spawner.Runner.SessionInfo.Name;
|
||||
}
|
||||
|
||||
_playerDataManager = Object.FindFirstObjectByType<PlayerDataManager>();
|
||||
if (_playerDataManager != null)
|
||||
{
|
||||
_playerDataManager.OnChatMessageReceived += OnChatMessageReceived;
|
||||
}
|
||||
if (_playerDataManager != null) _playerDataManager.OnChatMessageReceived += OnChatMessageReceived;
|
||||
}
|
||||
|
||||
private async void OnCreateRoomClicked()
|
||||
{
|
||||
if (_confirmCreateBtn != null) _confirmCreateBtn.SetEnabled(false);
|
||||
if (_createErrorLabel != null) _createErrorLabel.style.display = DisplayStyle.None;
|
||||
|
||||
var spawner = BasicSpawner.Instance;
|
||||
if (spawner == null)
|
||||
{
|
||||
ShowCreateError("System Error: Spawner missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Auto-generate ID if empty
|
||||
string id = (_roomIDInput != null && !string.IsNullOrEmpty(_roomIDInput.value))
|
||||
? _roomIDInput.value.Trim()
|
||||
: "ROOM_" + Random.Range(1000, 9999).ToString();
|
||||
|
||||
if (_roomIDInput != null) _roomIDInput.value = id;
|
||||
|
||||
// Name defaults to ID if empty
|
||||
string name = (_roomNameInput != null && !string.IsNullOrEmpty(_roomNameInput.value))
|
||||
? _roomNameInput.value.Trim()
|
||||
: id;
|
||||
|
||||
string pass = (_passToggle != null && _passToggle.value && _roomPassInput != null)
|
||||
? _roomPassInput.value
|
||||
: null;
|
||||
|
||||
try
|
||||
{
|
||||
if (spawner == null) { ShowCreateError("System Error: Spawner missing. Please re-enter the Lobby."); return; }
|
||||
string id = (_roomIDInput != null && !string.IsNullOrEmpty(_roomIDInput.value)) ? _roomIDInput.value.Trim() : "ROOM_" + Random.Range(1000, 9999).ToString();
|
||||
string name = (_roomNameInput != null && !string.IsNullOrEmpty(_roomNameInput.value)) ? _roomNameInput.value.Trim() : id;
|
||||
string pass = (_passToggle != null && _passToggle.value && _roomPassInput != null) ? _roomPassInput.value : null;
|
||||
try {
|
||||
bool success = await spawner.StartHost(id, name, pass);
|
||||
if (success)
|
||||
{
|
||||
ShowLounge(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowCreateError("Failed to create room. ID might be taken.");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
ShowCreateError("Network Error: " + ex.Message);
|
||||
}
|
||||
if (success) ShowLounge(name);
|
||||
else ShowCreateError("Failed to create room. ID might be taken.");
|
||||
} catch (System.Exception ex) { ShowCreateError("Network Error: " + ex.Message); }
|
||||
}
|
||||
|
||||
private void ShowCreateError(string message)
|
||||
{
|
||||
if (_createErrorLabel != null)
|
||||
{
|
||||
_createErrorLabel.text = message;
|
||||
_createErrorLabel.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
if (_createErrorLabel != null) { _createErrorLabel.text = message; _createErrorLabel.style.display = DisplayStyle.Flex; }
|
||||
if (_confirmCreateBtn != null) _confirmCreateBtn.SetEnabled(true);
|
||||
}
|
||||
|
||||
@@ -396,30 +186,17 @@ namespace Hallucinate.UI
|
||||
{
|
||||
if (_roomItemTemplate == null) continue;
|
||||
var item = _roomItemTemplate.Instantiate();
|
||||
|
||||
string displayName = session.Name;
|
||||
if (session.Properties.TryGetValue("rn", out var rnProp))
|
||||
{
|
||||
displayName = rnProp;
|
||||
}
|
||||
|
||||
if (session.Properties.TryGetValue("rn", out var rnProp)) displayName = rnProp;
|
||||
item.Q<Label>("RoomName").text = displayName;
|
||||
item.Q<Label>("PlayerCount").text = $"{session.PlayerCount}/{session.MaxPlayers}";
|
||||
|
||||
var statusBadge = item.Q<Label>("StatusBadge");
|
||||
if (statusBadge != null) statusBadge.text = GetT("ROOM_STATUS_WAITING");
|
||||
|
||||
bool needsPass = session.Properties.ContainsKey("pw");
|
||||
var lockIcon = item.Q<Label>("LockIcon");
|
||||
if (lockIcon != null) lockIcon.style.display = needsPass ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
|
||||
var joinBtn = item.Q<Button>("JoinBtn");
|
||||
if (joinBtn != null)
|
||||
{
|
||||
joinBtn.text = GetT("ROOM_JOIN_BTN");
|
||||
joinBtn.clicked += () => OnRoomItemClicked(session);
|
||||
}
|
||||
|
||||
if (joinBtn != null) { joinBtn.text = GetT("ROOM_JOIN_BTN"); joinBtn.clicked += () => OnRoomItemClicked(session); }
|
||||
_roomList.Add(item);
|
||||
}
|
||||
}
|
||||
@@ -434,10 +211,7 @@ namespace Hallucinate.UI
|
||||
if (_joinPassError != null) _joinPassError.style.display = DisplayStyle.None;
|
||||
if (_joinPassInput != null) _joinPassInput.value = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
await JoinRoom(session.Name, null);
|
||||
}
|
||||
else await JoinRoom(session.Name, null);
|
||||
}
|
||||
|
||||
private async void OnConfirmPasswordClicked()
|
||||
@@ -448,81 +222,27 @@ namespace Hallucinate.UI
|
||||
await JoinRoom(_selectedSession.Name, pass);
|
||||
}
|
||||
|
||||
private async Task JoinRoom(string sessionName, string password)
|
||||
{
|
||||
if (BasicSpawner.Instance != null)
|
||||
{
|
||||
bool success = await BasicSpawner.Instance.StartClient(sessionName, password);
|
||||
if (success) ShowLounge(sessionName);
|
||||
}
|
||||
}
|
||||
private async Task JoinRoom(string sessionName, string password) { if (BasicSpawner.Instance != null) { if (await BasicSpawner.Instance.StartClient(sessionName, password)) ShowLounge(sessionName); } }
|
||||
private void OnReadyClicked() { var runner = Object.FindFirstObjectByType<NetworkRunner>(); if (runner != null && _playerDataManager != null && _playerDataManager.TryGetPlayerMetaData(runner.LocalPlayer, out var myData)) _playerDataManager.RPC_SetReady(runner.LocalPlayer, !myData.IsReady); }
|
||||
private void OnStartClicked() { BasicSpawner.Instance?.StartGame(); }
|
||||
private async void OnLeaveLoungeClicked() { var runner = Object.FindFirstObjectByType<NetworkRunner>(); if (runner != null) await runner.Shutdown(); if (_playerDataManager != null) _playerDataManager.OnChatMessageReceived -= OnChatMessageReceived; ShowJoin(); }
|
||||
|
||||
private void OnReadyClicked()
|
||||
{
|
||||
var runner = Object.FindFirstObjectByType<NetworkRunner>();
|
||||
if (runner != null && _playerDataManager != null)
|
||||
{
|
||||
if (_playerDataManager.TryGetPlayerMetaData(runner.LocalPlayer, out var myData))
|
||||
{
|
||||
_playerDataManager.RPC_SetReady(runner.LocalPlayer, !myData.IsReady);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStartClicked()
|
||||
{
|
||||
BasicSpawner.Instance?.StartGame();
|
||||
}
|
||||
|
||||
private async void OnLeaveLoungeClicked()
|
||||
{
|
||||
var runner = Object.FindFirstObjectByType<NetworkRunner>();
|
||||
if (runner != null)
|
||||
{
|
||||
await runner.Shutdown();
|
||||
}
|
||||
if (_playerDataManager != null)
|
||||
{
|
||||
_playerDataManager.OnChatMessageReceived -= OnChatMessageReceived;
|
||||
}
|
||||
ShowJoin();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (_loungeContainer != null && _loungeContainer.style.display == DisplayStyle.Flex)
|
||||
{
|
||||
UpdateLoungeUI();
|
||||
}
|
||||
}
|
||||
public override void Update() { if (_loungeContainer != null && _loungeContainer.style.display == DisplayStyle.Flex) UpdateLoungeUI(); }
|
||||
|
||||
private void UpdateLoungeUI()
|
||||
{
|
||||
var runner = Object.FindFirstObjectByType<NetworkRunner>();
|
||||
if (runner == null) return;
|
||||
|
||||
if (_playerDataManager == null)
|
||||
{
|
||||
_playerDataManager = Object.FindFirstObjectByType<PlayerDataManager>();
|
||||
if (_playerDataManager != null)
|
||||
{
|
||||
_playerDataManager.OnChatMessageReceived += OnChatMessageReceived;
|
||||
}
|
||||
}
|
||||
|
||||
if (_playerDataManager == null || _playerDataManager.Object == null || !_playerDataManager.Object.IsValid) return;
|
||||
var spawner = BasicSpawner.Instance;
|
||||
if (spawner == null) return;
|
||||
var runner = spawner.Runner;
|
||||
if (runner == null || _playerDataManager == null || _playerDataManager.Object == null || !_playerDataManager.Object.IsValid) return;
|
||||
|
||||
PlayerRef hostRef = PlayerRef.None;
|
||||
PlayerRef guestRef = PlayerRef.None;
|
||||
|
||||
var sortedPlayers = runner.ActivePlayers.OrderBy(p => p.PlayerId).ToList();
|
||||
if (sortedPlayers.Count > 0) hostRef = sortedPlayers[0];
|
||||
if (sortedPlayers.Count > 1) guestRef = sortedPlayers[1];
|
||||
|
||||
if (runner.SessionInfo != null && runner.SessionInfo.Properties.TryGetValue("rn", out var rnProp))
|
||||
{
|
||||
_loungeRoomName.text = rnProp.ToString().ToUpper();
|
||||
}
|
||||
if (runner.SessionInfo != null && runner.SessionInfo.Properties.TryGetValue("rn", out var rnProp)) _loungeRoomName.text = rnProp.ToString().ToUpper();
|
||||
|
||||
if (hostRef != PlayerRef.None && _playerDataManager.TryGetPlayerMetaData(hostRef, out var hostData))
|
||||
{
|
||||
@@ -530,11 +250,7 @@ namespace Hallucinate.UI
|
||||
_hostStatusLabel.text = hostData.IsReady ? GetT("LOBBY_READY") : GetT("LOBBY_NOT_READY");
|
||||
_hostStatusLabel.style.color = hostData.IsReady ? Color.green : Color.red;
|
||||
}
|
||||
else if (hostRef != PlayerRef.None)
|
||||
{
|
||||
_hostNameLabel.text = GetT("LOBBY_SYNCING");
|
||||
_hostStatusLabel.text = "-";
|
||||
}
|
||||
else if (hostRef != PlayerRef.None) { _hostNameLabel.text = GetT("LOBBY_SYNCING"); _hostStatusLabel.text = "-"; }
|
||||
|
||||
if (guestRef != PlayerRef.None && _playerDataManager.TryGetPlayerMetaData(guestRef, out var guestData))
|
||||
{
|
||||
@@ -542,66 +258,23 @@ namespace Hallucinate.UI
|
||||
_guestStatusLabel.text = guestData.IsReady ? GetT("LOBBY_READY") : GetT("LOBBY_NOT_READY");
|
||||
_guestStatusLabel.style.color = guestData.IsReady ? Color.green : Color.red;
|
||||
}
|
||||
else if (runner.ActivePlayers.Count() >= 2)
|
||||
{
|
||||
_guestNameLabel.text = GetT("LOBBY_SYNCING");
|
||||
_guestStatusLabel.text = "-";
|
||||
}
|
||||
else
|
||||
{
|
||||
_guestNameLabel.text = GetT("LOBBY_WAITING_LABEL");
|
||||
_guestStatusLabel.text = "-";
|
||||
_guestStatusLabel.style.color = Color.gray;
|
||||
}
|
||||
else if (runner.ActivePlayers.Count() >= 2) { _guestNameLabel.text = GetT("LOBBY_SYNCING"); _guestStatusLabel.text = "-"; }
|
||||
else { _guestNameLabel.text = GetT("LOBBY_WAITING_LABEL"); _guestStatusLabel.text = "-"; _guestStatusLabel.style.color = Color.gray; }
|
||||
|
||||
bool allReady = true;
|
||||
int playerCount = 0;
|
||||
foreach (var p in runner.ActivePlayers)
|
||||
{
|
||||
playerCount++;
|
||||
if (_playerDataManager.TryGetPlayerMetaData(p, out var data))
|
||||
{
|
||||
if (!data.IsReady) allReady = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
allReady = false;
|
||||
}
|
||||
}
|
||||
foreach (var p in runner.ActivePlayers) { playerCount++; if (_playerDataManager.TryGetPlayerMetaData(p, out var data)) { if (!data.IsReady) allReady = false; } else allReady = false; }
|
||||
|
||||
bool isHost = runner.LocalPlayer == hostRef;
|
||||
if (_startBtn != null) { _startBtn.text = GetT("LOBBY_START_BTN"); _startBtn.style.display = isHost ? DisplayStyle.Flex : DisplayStyle.None; _startBtn.SetEnabled(allReady && playerCount >= 2); }
|
||||
|
||||
if (_startBtn != null)
|
||||
if (_readyBtn != null && _playerDataManager.TryGetPlayerMetaData(runner.LocalPlayer, out var myData))
|
||||
{
|
||||
_startBtn.text = GetT("LOBBY_START_BTN");
|
||||
_startBtn.style.display = isHost ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
_startBtn.SetEnabled(allReady && playerCount >= 2);
|
||||
}
|
||||
|
||||
if (_readyBtn != null)
|
||||
{
|
||||
if (_playerDataManager.TryGetPlayerMetaData(runner.LocalPlayer, out var myData))
|
||||
{
|
||||
if (myData.IsReady)
|
||||
{
|
||||
_readyBtn.text = GetT("LOBBY_UNREADY_BTN");
|
||||
_readyBtn.style.backgroundColor = new StyleColor(Color.green);
|
||||
_readyBtn.style.color = new StyleColor(Color.black);
|
||||
}
|
||||
else
|
||||
{
|
||||
_readyBtn.text = GetT("LOBBY_READY_BTN");
|
||||
_readyBtn.style.backgroundColor = new StyleColor(new Color(0.2f, 0.2f, 0.2f, 0.8f));
|
||||
_readyBtn.style.color = new StyleColor(Color.white);
|
||||
}
|
||||
}
|
||||
if (myData.IsReady) { _readyBtn.text = GetT("LOBBY_UNREADY_BTN"); _readyBtn.style.backgroundColor = new StyleColor(Color.green); _readyBtn.style.color = new StyleColor(Color.black); }
|
||||
else { _readyBtn.text = GetT("LOBBY_READY_BTN"); _readyBtn.style.backgroundColor = new StyleColor(new Color(0.2f, 0.2f, 0.2f, 0.8f)); _readyBtn.style.color = new StyleColor(Color.white); }
|
||||
}
|
||||
}
|
||||
|
||||
private async void Invoke(string methodName, float delay)
|
||||
{
|
||||
await Task.Delay((int)(delay * 1000));
|
||||
if (methodName == nameof(RegisterSpawnerEvents)) RegisterSpawnerEvents();
|
||||
}
|
||||
private async void Invoke(string methodName, float delay) { await Task.Delay((int)(delay * 1000)); if (methodName == nameof(RegisterSpawnerEvents)) RegisterSpawnerEvents(); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ MonoBehaviour:
|
||||
m_ScaleMode: 1
|
||||
m_ReferenceSpritePixelsPerUnit: 100
|
||||
m_PixelsPerUnit: 100
|
||||
m_Scale: 1.8199999
|
||||
m_Scale: 1
|
||||
m_ReferenceDpi: 96
|
||||
m_FallbackDpi: 96
|
||||
m_ReferenceResolution: {x: 1200, y: 800}
|
||||
|
||||
Reference in New Issue
Block a user