Update
This commit is contained in:
14
.idea/.idea.HALLUCINATE/.idea/workspace.xml
generated
14
.idea/.idea.HALLUCINATE/.idea/workspace.xml
generated
@@ -11,21 +11,12 @@
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="EmbeddingIndexingInfo">
|
||||
<option name="cachedIndexableFilesCount" value="1" />
|
||||
<option name="cachedIndexableFilesCount" value="39" />
|
||||
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="HighlightingSettingsPerFile">
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Scripts/Attributes/Health.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Scripts/Interactables/BaseInteractable.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Scripts/Interactables/HealthInteractable.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Scripts/UI/LobbyController.cs" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Third Parties/Photon/Fusion/Editor/Fusion.Unity.Editor.cs" root0="SKIP_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/UI/MainPanelSettings.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Library/PackageCache/com.unity.ugui@bb329a87fcdc/Runtime/TMP/TMP_PackageResourceImporter.cs" root0="SKIP_HIGHLIGHTING" />
|
||||
</component>
|
||||
<component name="McpProjectServerCommands">
|
||||
<commands />
|
||||
<urls />
|
||||
@@ -140,7 +131,8 @@
|
||||
<workItem from="1777150520438" duration="58000" />
|
||||
<workItem from="1777150592854" duration="4699000" />
|
||||
<workItem from="1777181837663" duration="1519000" />
|
||||
<workItem from="1777269364664" duration="33315000" />
|
||||
<workItem from="1777269364664" duration="40284000" />
|
||||
<workItem from="1777373072815" duration="1852000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Hallucinate.UI
|
||||
protected VisualElement root;
|
||||
protected UIManager uiManager;
|
||||
|
||||
public VisualElement Root => root; // Thêm thuộc tính này
|
||||
|
||||
public virtual void Initialize(VisualElement uxmlRoot, UIManager manager)
|
||||
{
|
||||
root = uxmlRoot;
|
||||
|
||||
43
Assets/Scripts/UI/FirebaseService.cs
Normal file
43
Assets/Scripts/UI/FirebaseService.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace Hallucinate.UI
|
||||
{
|
||||
public static class FirebaseService
|
||||
{
|
||||
// Thay link database của bạn vào đây
|
||||
private const string BASE_URL = "https://YOUR_FIREBASE_URL.firebaseio.com/users";
|
||||
|
||||
public static async Task<bool> IsUsernameTaken(string username)
|
||||
{
|
||||
string url = $"{BASE_URL}/{username}.json";
|
||||
using (UnityWebRequest request = UnityWebRequest.Get(url))
|
||||
{
|
||||
var operation = request.SendWebRequest();
|
||||
while (!operation.isDone) await Task.Yield();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success) return false;
|
||||
|
||||
// Nếu kết quả trả về không phải "null" nghĩa là user đã tồn tại
|
||||
return request.downloadHandler.text != "null";
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<bool> RegisterUser(string username)
|
||||
{
|
||||
string url = $"{BASE_URL}/{username}.json";
|
||||
string jsonData = "{\"created_at\": \"" + DateTime.Now.ToString() + "\"}";
|
||||
|
||||
using (UnityWebRequest request = UnityWebRequest.Put(url, jsonData))
|
||||
{
|
||||
var operation = request.SendWebRequest();
|
||||
while (!operation.isDone) await Task.Yield();
|
||||
|
||||
return request.result == UnityWebRequest.Result.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/UI/FirebaseService.cs.meta
Normal file
2
Assets/Scripts/UI/FirebaseService.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf13e7d21e483574882c6b687a6ae19c
|
||||
90
Assets/Scripts/UI/LoginController.cs
Normal file
90
Assets/Scripts/UI/LoginController.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Hallucinate.UI
|
||||
{
|
||||
public class LoginController : BaseUIController
|
||||
{
|
||||
private TextField _nameInput;
|
||||
private Label _errorLabel;
|
||||
private Button _confirmBtn;
|
||||
|
||||
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
|
||||
{
|
||||
base.Initialize(uxmlRoot, manager);
|
||||
|
||||
_nameInput = root.Q<TextField>("UsernameInput");
|
||||
_errorLabel = root.Q<Label>("ErrorMsg");
|
||||
_confirmBtn = root.Q<Button>("ConfirmBtn");
|
||||
|
||||
if (_confirmBtn != null)
|
||||
_confirmBtn.clicked += OnConfirmClicked;
|
||||
}
|
||||
|
||||
private async void OnConfirmClicked()
|
||||
{
|
||||
string username = _nameInput.value.Trim();
|
||||
|
||||
if (string.IsNullOrEmpty(username))
|
||||
{
|
||||
ShowError("Name cannot be empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
_confirmBtn.SetEnabled(false);
|
||||
_confirmBtn.text = "CHECKING...";
|
||||
|
||||
// 1. Kiểm tra trùng tên trên Firebase
|
||||
bool isTaken = await FirebaseService.IsUsernameTaken(username);
|
||||
|
||||
if (isTaken)
|
||||
{
|
||||
ShowError("This name is already taken!");
|
||||
_confirmBtn.SetEnabled(true);
|
||||
_confirmBtn.text = "CONFIRM";
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2. Đăng ký user mới
|
||||
bool success = await FirebaseService.RegisterUser(username);
|
||||
if (success)
|
||||
{
|
||||
// 3. Lưu lại và đóng popup
|
||||
PlayerPrefs.SetString("Username", username);
|
||||
PlayerPrefs.Save();
|
||||
Debug.Log($"[Login] Registered as {username}");
|
||||
|
||||
// Thông báo cho UIManager biết đã login xong
|
||||
uiManager.OnLoginSuccess();
|
||||
await PlayTransitionOut();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowError("Connection error!");
|
||||
_confirmBtn.SetEnabled(true);
|
||||
_confirmBtn.text = "CONFIRM";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowError(string msg)
|
||||
{
|
||||
if (_errorLabel == null) return;
|
||||
_errorLabel.text = msg;
|
||||
_errorLabel.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
|
||||
public override async Task PlayTransitionIn()
|
||||
{
|
||||
// Login hiện ra như một overlay trung tâm
|
||||
if (root != null)
|
||||
{
|
||||
root.style.translate = new StyleTranslate(new Translate(0, 0));
|
||||
root.style.opacity = 0;
|
||||
}
|
||||
Show();
|
||||
await PrimeTween.Tween.Custom(0f, 1f, duration: 0.5f, onValueChange: val => root.style.opacity = val);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/UI/LoginController.cs.meta
Normal file
2
Assets/Scripts/UI/LoginController.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fbd606c21d317da47820446e4da1c55b
|
||||
@@ -19,10 +19,12 @@ namespace Hallucinate.UI
|
||||
_tabTitle = root.Q<Label>("TabTitle");
|
||||
_content = root.Q<ScrollView>("SettingsContent");
|
||||
|
||||
// Logic đóng khi nhấn vào vùng nền bên ngoài sidebar
|
||||
root.RegisterCallback<ClickEvent>(evt => {
|
||||
// Đăng ký sự kiện Click vào vùng nền tối
|
||||
root.RegisterCallback<PointerDownEvent>(evt => {
|
||||
// Nếu click trực tiếp vào SettingsRoot (không phải sidebar)
|
||||
if (evt.target == root)
|
||||
{
|
||||
Debug.Log("[Settings] Clicked outside sidebar, closing...");
|
||||
uiManager.ToggleSettings();
|
||||
}
|
||||
});
|
||||
@@ -43,14 +45,13 @@ namespace Hallucinate.UI
|
||||
|
||||
public override async Task PlayTransitionIn()
|
||||
{
|
||||
// Reset vị trí root về 0 (Overlay trên màn hình hiện tại)
|
||||
if (root != null)
|
||||
{
|
||||
root.style.translate = new StyleTranslate(new Translate(0, 0));
|
||||
root.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
|
||||
// Trượt sidebar từ trái vào
|
||||
// Hiệu ứng trượt sidebar
|
||||
_sidebar.style.translate = new StyleTranslate(new Translate(Length.Percent(-100), 0));
|
||||
await Tween.Custom(-100f, 0f, duration: 0.4f, ease: Ease.OutQuad,
|
||||
onValueChange: val => _sidebar.style.translate = new StyleTranslate(new Translate(Length.Percent(val), 0)));
|
||||
@@ -58,7 +59,6 @@ namespace Hallucinate.UI
|
||||
|
||||
public override async Task PlayTransitionOut()
|
||||
{
|
||||
// Trượt sidebar ra trái
|
||||
await Tween.Custom(0f, -100f, duration: 0.4f, ease: Ease.InQuad,
|
||||
onValueChange: val => _sidebar.style.translate = new StyleTranslate(new Translate(Length.Percent(val), 0)));
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using PrimeTween;
|
||||
using OnlyScove.Scripts; // Namespace của InputReader
|
||||
using OnlyScove.Scripts;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
@@ -40,12 +40,14 @@ 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 mainMenuTemplate;
|
||||
[SerializeField] private VisualTreeAsset lobbyTemplate;
|
||||
[SerializeField] private VisualTreeAsset profileTemplate;
|
||||
[SerializeField] private VisualTreeAsset settingsTemplate;
|
||||
[SerializeField] private VisualTreeAsset hudTemplate;
|
||||
|
||||
private LoginController _loginController;
|
||||
private MainMenuController _mainMenuController;
|
||||
private SettingsController _settingsController;
|
||||
private List<VisualElement> _trailSegments = new List<VisualElement>();
|
||||
@@ -79,7 +81,6 @@ namespace Hallucinate.UI
|
||||
|
||||
_rootElement.RegisterCallback<PointerDownEvent>(OnGlobalClick, TrickleDown.TrickleDown);
|
||||
|
||||
// Đăng ký sự kiện từ InputReader (Chuẩn New Input System)
|
||||
if (inputReader != null)
|
||||
{
|
||||
inputReader.OnToggleSettingsEvent += ToggleSettings;
|
||||
@@ -94,6 +95,29 @@ namespace Hallucinate.UI
|
||||
}
|
||||
#endif
|
||||
InitializeControllers();
|
||||
|
||||
// KIỂM TRA LOGIN
|
||||
CheckLoginStatus();
|
||||
}
|
||||
|
||||
private void CheckLoginStatus()
|
||||
{
|
||||
string savedName = PlayerPrefs.GetString("Username", "");
|
||||
if (string.IsNullOrEmpty(savedName))
|
||||
{
|
||||
_ = Push<LoginController>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"[UIManager] Welcome back, {savedName}!");
|
||||
_ = Push<MainMenuController>();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnLoginSuccess()
|
||||
{
|
||||
// Sau khi login xong thì hiện MainMenu
|
||||
_ = Push<MainMenuController>();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -117,6 +141,7 @@ namespace Hallucinate.UI
|
||||
if (!_isSettingsOpen)
|
||||
{
|
||||
_isSettingsOpen = true;
|
||||
_settingsController.Root.BringToFront();
|
||||
_cursorLayer.BringToFront();
|
||||
await _settingsController.PlayTransitionIn();
|
||||
}
|
||||
@@ -261,6 +286,7 @@ namespace Hallucinate.UI
|
||||
|
||||
private void InitializeControllers()
|
||||
{
|
||||
_loginController = RegisterController<LoginController>(loginTemplate);
|
||||
_mainMenuController = RegisterController<MainMenuController>(mainMenuTemplate);
|
||||
if (_mainMenuController != null && gameIcon != null) _mainMenuController.SetGameIcon(gameIcon);
|
||||
|
||||
@@ -268,8 +294,6 @@ namespace Hallucinate.UI
|
||||
RegisterController<ProfileController>(profileTemplate);
|
||||
_settingsController = RegisterController<SettingsController>(settingsTemplate);
|
||||
RegisterController<HUDController>(hudTemplate);
|
||||
|
||||
_ = Push<MainMenuController>();
|
||||
}
|
||||
|
||||
private T RegisterController<T>(VisualTreeAsset template) where T : BaseUIController, new()
|
||||
|
||||
@@ -60,7 +60,7 @@ MonoBehaviour:
|
||||
- folder: {fileID: 102900000, guid: 8c41df02b38b2ee40b792b146c0493f2, type: 3}
|
||||
folderIcon: {fileID: 2800000, guid: 9687b8a9002844d4b8ece997ce390043, type: 3}
|
||||
overlayIcon: {fileID: 0}
|
||||
- folder: {fileID: 102900000, guid: 4e6e9b4a0c2e35242b749c3b025c2b6d, type: 3}
|
||||
- folder: {fileID: 102900000, guid: 55d9223ee943a5248a49f0c45b440900, type: 3}
|
||||
folderIcon: {fileID: 2800000, guid: f98ab23e70af0464ba10b820ef66cf70, type: 3}
|
||||
overlayIcon: {fileID: 0}
|
||||
- folder: {fileID: 102900000, guid: e4342b7ac2b8c524bbfd5ed650d13a32, type: 3}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e6e9b4a0c2e35242b749c3b025c2b6d
|
||||
guid: 55d9223ee943a5248a49f0c45b440900
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 80 KiB |
@@ -1,130 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6e88709eb6360c4187aedc8a351b609
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 16384
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 2
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,12 +1,51 @@
|
||||
/* Global Styles for Hallucinate UI */
|
||||
/* osu!lazer-inspired — extends existing rules, nothing removed */
|
||||
|
||||
/* ============================================================
|
||||
DESIGN TOKENS
|
||||
============================================================ */
|
||||
:root {
|
||||
/* --- Giữ nguyên biến cũ --- */
|
||||
--primary-color: #ffffff;
|
||||
--accent-color: #00ffcc;
|
||||
--background-blur: rgba(0, 0, 0, 0.5);
|
||||
--font-main: resource("Fonts/Ancient Medium SDF"); /* Place holder font */
|
||||
--font-main: resource("Fonts/Ancient Medium SDF");
|
||||
|
||||
/* --- Spacing system (base 4px) --- */
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
|
||||
/* --- Color system --- */
|
||||
--color-surface: rgba(0, 0, 0, 0.65);
|
||||
--color-surface-light: rgba(255, 255, 255, 0.06);
|
||||
--color-border: rgba(255, 255, 255, 0.12);
|
||||
--color-border-hover: rgba(255, 255, 255, 0.28);
|
||||
|
||||
/* Palette — mỗi nút 1 màu (giống osu) */
|
||||
--color-btn-settings: #7B6EE8; /* tím */
|
||||
--color-btn-join: #4DC8A0; /* teal */
|
||||
--color-btn-create: #E8834D; /* cam */
|
||||
--color-btn-profile: #E84D8A; /* hồng */
|
||||
--color-btn-exit: #888888; /* xám trung tính */
|
||||
|
||||
/* Text */
|
||||
--color-text-primary: rgba(255, 255, 255, 0.95);
|
||||
--color-text-secondary: rgba(255, 255, 255, 0.55);
|
||||
|
||||
/* --- Border radius --- */
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 10px;
|
||||
--radius-lg: 16px;
|
||||
--radius-pill: 999px;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
BASE RESET
|
||||
============================================================ */
|
||||
.screen-root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -14,24 +53,277 @@
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
BUTTON — SPRING (giữ nguyên, chỉ thêm visual)
|
||||
============================================================ */
|
||||
.button-spring {
|
||||
/* --- Giữ nguyên animation cũ --- */
|
||||
transition-duration: 0.1s;
|
||||
transition-timing-function: ease-out-back;
|
||||
|
||||
/* --- Thêm visual --- */
|
||||
height: 48px;
|
||||
padding-left: var(--space-4);
|
||||
padding-right: var(--space-4);
|
||||
border-radius: var(--radius-md);
|
||||
border-width: 0;
|
||||
-unity-font-definition: resource("Fonts/Ancient Medium SDF");
|
||||
font-size: 15px;
|
||||
color: var(--color-text-primary);
|
||||
-unity-font-style: bold;
|
||||
cursor: link;
|
||||
|
||||
/* Màu mặc định — bị override bởi modifier class bên dưới */
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.button-spring:hover {
|
||||
scale: 1.05;
|
||||
background-color: rgba(255, 255, 255, 0.18);
|
||||
}
|
||||
|
||||
.button-spring:active {
|
||||
scale: 0.9;
|
||||
}
|
||||
|
||||
/* Per-button accent colors (gán thêm class vào UXML) */
|
||||
.btn-settings { background-color: var(--color-btn-settings); }
|
||||
.btn-settings:hover { background-color: #9080F0; }
|
||||
|
||||
.btn-join { background-color: var(--color-btn-join); }
|
||||
.btn-join:hover { background-color: #60DEB8; }
|
||||
|
||||
.btn-create { background-color: var(--color-btn-create); }
|
||||
.btn-create:hover { background-color: #F09A68; }
|
||||
|
||||
.btn-profile { background-color: var(--color-btn-profile); }
|
||||
.btn-profile:hover { background-color: #F060A0; }
|
||||
|
||||
.btn-exit { background-color: var(--color-btn-exit); }
|
||||
.btn-exit:hover { background-color: #AAAAAA; }
|
||||
|
||||
/* ============================================================
|
||||
RIBBON — dải băng main menu
|
||||
============================================================ */
|
||||
.ribbon {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--color-surface);
|
||||
padding-top: var(--space-2);
|
||||
padding-bottom: var(--space-2);
|
||||
padding-left: var(--space-6);
|
||||
padding-right: var(--space-6);
|
||||
border-radius: var(--radius-lg);
|
||||
border-width: 1px;
|
||||
border-color: var(--color-border);
|
||||
|
||||
/* gap giữa các button */
|
||||
/* Unity UIToolkit không có gap trực tiếp, dùng margin trên button */
|
||||
}
|
||||
|
||||
/* Spacing giữa các nút trong ribbon */
|
||||
.ribbon .button-spring {
|
||||
margin-left: var(--space-2);
|
||||
margin-right: var(--space-2);
|
||||
min-width: 96px;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
LOGO
|
||||
============================================================ */
|
||||
.logo-pulse {
|
||||
/* Pulse effect will be handled via PrimeTween in Controller,
|
||||
but we can define base styles here */
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
align-self: center;
|
||||
justify-content: center;
|
||||
|
||||
/* Thêm visual */
|
||||
border-radius: var(--radius-pill);
|
||||
border-width: 2px;
|
||||
border-color: var(--color-border-hover);
|
||||
background-color: rgba(255, 255, 255, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
SURFACE / PANEL — dùng cho Lobby, Profile, Settings
|
||||
============================================================ */
|
||||
.panel-glass {
|
||||
background-color: var(--color-surface);
|
||||
border-radius: var(--radius-lg);
|
||||
border-width: 1px;
|
||||
border-color: var(--color-border);
|
||||
padding: var(--space-6);
|
||||
}
|
||||
|
||||
.panel-glass--right {
|
||||
/* Right pane trong Lobby / Profile */
|
||||
width: 40%;
|
||||
height: 100%;
|
||||
border-radius: 0;
|
||||
border-top-left-radius: var(--radius-lg);
|
||||
border-bottom-left-radius: var(--radius-lg);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
TYPOGRAPHY
|
||||
============================================================ */
|
||||
.text-heading {
|
||||
font-size: 28px;
|
||||
-unity-font-style: bold;
|
||||
color: var(--color-text-primary);
|
||||
-unity-font-definition: resource("Fonts/Ancient Medium SDF");
|
||||
}
|
||||
|
||||
.text-label {
|
||||
font-size: 13px;
|
||||
color: var(--color-text-secondary);
|
||||
-unity-font-definition: resource("Fonts/Ancient Medium SDF");
|
||||
}
|
||||
|
||||
.text-body {
|
||||
font-size: 15px;
|
||||
color: var(--color-text-primary);
|
||||
-unity-font-definition: resource("Fonts/Ancient Medium SDF");
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
INPUT FIELD
|
||||
============================================================ */
|
||||
.input-field {
|
||||
height: 44px;
|
||||
border-radius: var(--radius-md);
|
||||
border-width: 1px;
|
||||
border-color: var(--color-border);
|
||||
background-color: var(--color-surface-light);
|
||||
color: var(--color-text-primary);
|
||||
font-size: 14px;
|
||||
padding-left: var(--space-3);
|
||||
padding-right: var(--space-3);
|
||||
}
|
||||
|
||||
.input-field:focus {
|
||||
border-color: var(--color-border-hover);
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
SIDEBAR (Settings)
|
||||
============================================================ */
|
||||
.sidebar-tab {
|
||||
height: 48px;
|
||||
padding-left: var(--space-4);
|
||||
border-radius: var(--radius-sm);
|
||||
background-color: transparent;
|
||||
border-width: 0;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 14px;
|
||||
-unity-text-align: middle-left;
|
||||
margin-bottom: var(--space-1);
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
|
||||
.sidebar-tab:hover {
|
||||
background-color: var(--color-surface-light);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.sidebar-tab.active-tab {
|
||||
background-color: rgba(123, 110, 232, 0.2);
|
||||
color: var(--color-text-primary);
|
||||
border-left-color: var(--color-btn-settings);
|
||||
border-left-width: 3px;
|
||||
border-radius: 0;
|
||||
border-top-right-radius: var(--radius-sm);
|
||||
border-bottom-right-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
HUD
|
||||
============================================================ */
|
||||
.hud-root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
picking-mode: ignore;
|
||||
}
|
||||
|
||||
.hud-bar {
|
||||
border-radius: var(--radius-pill);
|
||||
border-width: 1px;
|
||||
border-color: var(--color-border);
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hud-slot {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: var(--radius-md);
|
||||
border-width: 1px;
|
||||
border-color: var(--color-border);
|
||||
background-color: var(--color-surface);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hud-slot--active {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-color: var(--color-border-hover);
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.hud-text-debug {
|
||||
font-size: 12px;
|
||||
color: var(--color-text-secondary);
|
||||
-unity-font-definition: resource("Fonts/Ancient Medium SDF");
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
READY BUTTON (Lounge)
|
||||
============================================================ */
|
||||
.btn-ready {
|
||||
height: 56px;
|
||||
min-width: 160px;
|
||||
border-radius: var(--radius-md);
|
||||
border-width: 2px;
|
||||
border-color: var(--color-btn-join);
|
||||
background-color: transparent;
|
||||
color: var(--color-btn-join);
|
||||
font-size: 16px;
|
||||
-unity-font-style: bold;
|
||||
transition-duration: 0.15s;
|
||||
}
|
||||
|
||||
.btn-ready.is-ready {
|
||||
background-color: var(--color-btn-join);
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
SCROLL VIEW
|
||||
============================================================ */
|
||||
.scroll-list {
|
||||
background-color: transparent;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.room-item {
|
||||
height: 56px;
|
||||
margin-bottom: var(--space-2);
|
||||
border-radius: var(--radius-md);
|
||||
background-color: var(--color-surface-light);
|
||||
border-width: 1px;
|
||||
border-color: var(--color-border);
|
||||
padding-left: var(--space-4);
|
||||
padding-right: var(--space-4);
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
|
||||
.room-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-color: var(--color-border-hover);
|
||||
}
|
||||
|
||||
14
Assets/UI/LoginPopup.uxml
Normal file
14
Assets/UI/LoginPopup.uxml
Normal file
@@ -0,0 +1,14 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
|
||||
<Style src="project:/Assets/UI/Global.uss" />
|
||||
<ui:VisualElement name="LoginRoot" class="screen-root" style="background-color: rgba(0, 0, 0, 0.85); justify-content: center; align-items: center;">
|
||||
<ui:VisualElement name="Window" style="width: 400px; padding: 30px; background-color: #1a1a1a; border-radius: 15px; border-width: 2px; border-color: #333;">
|
||||
<ui:Label text="WELCOME TRAVELLER" style="font-size: 24px; -unity-font-style: bold; color: white; align-self: center; margin-bottom: 10px;" />
|
||||
<ui:Label text="Enter your username to begin" style="font-size: 14px; color: #888; align-self: center; margin-bottom: 25px;" />
|
||||
|
||||
<ui:TextField name="UsernameInput" placeholder-text="Your name..." style="margin-bottom: 10px;" />
|
||||
<ui:Label name="ErrorMsg" text="Name is already taken!" style="color: #ff4444; font-size: 12px; display: none; margin-bottom: 10px;" />
|
||||
|
||||
<ui:Button name="ConfirmBtn" text="CONFIRM" class="button-spring" style="height: 45px; background-color: #00ffcc; color: black; -unity-font-style: bold; margin-top: 10px;" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
10
Assets/UI/LoginPopup.uxml.meta
Normal file
10
Assets/UI/LoginPopup.uxml.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f11f2cb91fbd4748bcbc70cd0f5afe7
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
Reference in New Issue
Block a user