Organize custom scripts and Shared under Assets/Scripts, and delete assembly definition files

This commit is contained in:
2026-07-01 20:36:56 +07:00
parent befc19bf37
commit 01048074ee
183 changed files with 180 additions and 3456 deletions

View File

@@ -7,7 +7,186 @@
<configurations />
</component>
<component name="ChangeListManager">
<list default="true" id="d308d1cb-09fc-4331-ba20-00f7b43d1576" name="Changes" comment="" />
<list default="true" id="d308d1cb-09fc-4331-ba20-00f7b43d1576" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/BehavourTreeCore.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/BehavourTreeCore.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/ChatBubble.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/ChatBubble.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/FieldOfView.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/FieldOfView.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/GeminiService.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/GeminiService.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/KamikazeAI.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/KamikazeAI.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/Sequence.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/AI NPC/Sequence.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Audio.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Camera.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Duy.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Duy/LobbyManager.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Duy/LobbyManager.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Game.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Game/EloData.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Game/EloData.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Game/EloSystem.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Game/EloSystem.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Game/MatchEloManager.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Game/MatchEloManager.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/CharacterAutoSetup.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/CharacterAutoSetup.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/CharacterSetupSettings.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/CharacterSetupSettings.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/GameSettings.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/GameSettings.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/CrawlerAlgorithm.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/CrawlerAlgorithm.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/Extensions.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/Extensions.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/Interfaces.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/Interfaces/IMazeAlgorithm.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/Interfaces/IMazeAlgorithm.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MapLocation.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MapLocation.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MazeCellType.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MazeCellType.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MazeGrid.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MazeGrid.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MazeManager.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MazeManager.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MazeRenderer.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MazeRenderer.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MazeVisualProfile.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/MazeVisualProfile.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/Native.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/Native/NativeNoiseProvider.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/Native/NativeNoiseProvider.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/NoiseRecursiveGenerator.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/NoiseRecursiveGenerator.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/PrimsAlgorithm.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/PrimsAlgorithm.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/RecursiveAlgorithm.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/RecursiveAlgorithm.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/WilsonsAlgorithm.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/Maze/WilsonsAlgorithm.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/ObjectInteraction.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/ObjectInteraction.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/SettingsManager.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/GameSetup/SettingsManager.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Interaction.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Manager.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Manager/GameManager.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Manager/GameManager.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/BasicSpawner.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/BasicSpawner.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/FusionClientMovementBridge.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/FusionClientMovementBridge.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/MatchResultManager.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/MatchResultManager.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/PlayerData.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/PlayerData.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/PlayerDataManager.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/PlayerDataManager.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/PlayerInfo.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/PlayerInfo.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/PlayerInputData.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Network/PlayerInputData.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Others.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Others/StickyNote.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Others/StickyNote.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Player.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Trap.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Trap/TeleportTrap.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Trap/TeleportTrap.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Tuấn.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Tuấn/Plan.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/Tuấn/Plan.txt.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/BaseUIController.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/BaseUIController.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/Components.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/Components/VectorShapeElement.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/Components/VectorShapeElement.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/FirebaseConfig.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/FirebaseConfig.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/FirebaseService.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/FirebaseService.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/FirebaseTest.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/FirebaseTest.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/HUDController.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/HUDController.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/LobbyController.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/LobbyController.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/LocalizationManager.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/LocalizationManager.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/LoginController.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/LoginController.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/MainMenuController.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/MainMenuController.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/MouseMetricsHelper.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/MouseMetricsHelper.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/PauseMenuController.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/PauseMenuController.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/PerformanceOverlay.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/PerformanceOverlay.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/ProfileController.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/ProfileController.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/SettingsController.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/SettingsController.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/UIAudioHelper.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/UIAudioHelper.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/UIManager.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/UI/UIManager.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX/SlashMeshGenerator.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX/SlashMeshGenerator.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX/SukunaAbilityController.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX/SukunaAbilityController.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX/SukunaDomainController.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX/SukunaDomainController.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX/SukunaProjectile.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX/SukunaProjectile.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX/SukunaSlashEffect.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Baba_yaga/VFX/SukunaSlashEffect.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor/DomainResetter.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor/DomainResetter.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor/Game.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor/Game/Opsive.Shared.Editor.Game.dll" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor/Game/Opsive.Shared.Editor.Game.dll.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor/Opsive.Shared.Editor.asmdef" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor/Opsive.Shared.Editor.asmdef.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor/Utility.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor/Utility/Opsive.Shared.Editor.Utility.dll" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Editor/Utility/Opsive.Shared.Editor.Utility.dll.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Events.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Events/Opsive.Shared.Events.dll" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Events/Opsive.Shared.Events.dll.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Game.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Game/ObjectPool.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Game/ObjectPool.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Game/Opsive.Shared.Game.dll" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Game/Opsive.Shared.Game.dll.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Game/Scheduler.cs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Game/Scheduler.cs.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Inventory.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Inventory/Opsive.Shared.Inventory.dll" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Inventory/Opsive.Shared.Inventory.dll.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Opsive.Shared.asmdef" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Opsive.Shared.asmdef.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Utility.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Utility/Opsive.Shared.Utility.dll" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Shared/Utility/Opsive.Shared.Utility.dll.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/UltimateCharacterController_Documentation.pdf" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/UltimateCharacterController_Documentation.pdf.meta" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/UltimateCharacterController_README.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/UltimateCharacterController_README.txt.meta" beforeDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />

View File

@@ -1,78 +0,0 @@
using UnityEngine;
using UnityEngine.UIElements;
using PrimeTween;
using System.Threading.Tasks;
using DG.Tweening;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
namespace Baba_yaga.UI
{
public abstract class BaseUIController : ScriptableObject
{
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;
uiManager = manager;
// Đảm bảo ban đầu ẩn hết
Hide();
// Tự động gán âm thanh phản hồi cho các UI elements
UIAudioHelper.BindFeedback(root);
}
public virtual void Show()
{
if (root != null)
{
root.style.display = DisplayStyle.Flex;
root.style.opacity = 1;
}
}
public virtual void Hide()
{
if (root != null)
{
root.style.display = DisplayStyle.None;
}
}
protected string GetLoc(string key)
{
if (LocalizationManager.Instance != null)
return LocalizationManager.Instance.GetLocalizedString(key);
return key;
}
public virtual void Update() { }
/*public virtual async Task PlayTransitionIn()
{
if (root == null) return;
Show();
// Reset vị trí mặc định để tránh lỗi trôi màn hình
root.style.translate = new StyleTranslate(new Translate(Length.Percent(100), 0));
await Tween.Custom(100f, 0f, duration: 0.5f, ease: Ease.OutBack,
onValueChange: val => root.style.translate = new StyleTranslate(new Translate(Length.Percent(val), 0)));
}
public virtual async Task PlayTransitionOut()
{
if (root == null) return;
await Tween.Custom(0f, -100f, duration: 0.5f, ease: Ease.InBack,
onValueChange: val => root.style.translate = new StyleTranslate(new Translate(Length.Percent(val), 0)));
Hide();
}*/
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 872f8bfaee91588488a3393579135de9

View File

@@ -1,11 +0,0 @@
using UnityEngine;
namespace Baba_yaga.UI
{
[CreateAssetMenu(fileName = "FirebaseConfig", menuName = "BABA_YAGA/Configs/FirebaseConfig")]
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class FirebaseConfig : ScriptableObject
{
public string baseUrl;
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 0551a27408b84c040a2e009ae17debde

View File

@@ -1,87 +0,0 @@
using System;
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
namespace Baba_yaga.UI
{
public static class FirebaseService
{
private static string _baseUrl;
private static string BASE_URL
{
get
{
if (string.IsNullOrEmpty(_baseUrl))
{
// Nó sẽ tìm file tên "FirebaseConfig" trong bất kỳ folder "Resources" nào
var config = Resources.Load<FirebaseConfig>("FirebaseConfig");
if (config != null)
{
if (string.IsNullOrEmpty(config.baseUrl))
{
Debug.LogError("<color=red>[FirebaseService]</color> Base URL trong file FirebaseConfig đang trống!");
return null;
}
_baseUrl = config.baseUrl.TrimEnd('/');
}
else
{
Debug.LogError("<color=red>[FirebaseService]</color> Không tìm thấy file 'FirebaseConfig' trong folder Resources! " +
"Hãy đảm bảo bạn đã tạo file tại: Assets/.../Resources/FirebaseConfig");
return null;
}
}
return _baseUrl + "/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<Baba_yaga.Game.PlayerEloData> GetPlayerData(string username)
{
string url = $"{BASE_URL}/{username}/elo.json";
using (UnityWebRequest request = UnityWebRequest.Get(url))
{
var operation = request.SendWebRequest();
while (!operation.isDone) await Task.Yield();
if (request.result != UnityWebRequest.Result.Success || request.downloadHandler.text == "null")
{
return Baba_yaga.Game.PlayerEloData.Default;
}
return JsonUtility.FromJson<Baba_yaga.Game.PlayerEloData>(request.downloadHandler.text);
}
}
public static async Task<bool> SavePlayerData(string username, Baba_yaga.Game.PlayerEloData data)
{
string url = $"{BASE_URL}/{username}/elo.json";
string jsonData = JsonUtility.ToJson(data);
using (UnityWebRequest request = UnityWebRequest.Put(url, jsonData))
{
var operation = request.SendWebRequest();
while (!operation.isDone) await Task.Yield();
return request.result == UnityWebRequest.Result.Success;
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: bf13e7d21e483574882c6b687a6ae19c

View File

@@ -1,45 +0,0 @@
using UnityEngine;
using Baba_yaga.UI;
using System.Threading.Tasks;
namespace Baba_yaga.UI
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class FirebaseTest : MonoBehaviour
{
[Header("Settings")]
[SerializeField] private string testUsername = "TuanPlayer_01";
async void Start()
{
Debug.Log("<color=cyan>--- Firebase Test Started ---</color>");
// Bước 1: Kiểm tra xem username đã tồn tại chưa
Debug.Log($"[Firebase] Đang kiểm tra username: {testUsername}...");
bool isTaken = await FirebaseService.IsUsernameTaken(testUsername);
if (isTaken)
{
Debug.Log($"<color=yellow>[Firebase] Username '{testUsername}' đã tồn tại trên Database!</color>");
}
else
{
Debug.Log($"<color=green>[Firebase] Username '{testUsername}' còn trống. Tiến hành đăng ký...</color>");
// // Bước 2: Thử đăng ký user mới
// bool success = await FirebaseService.RegisterUser(testUsername);
//
// if (success)
// {
// Debug.Log("<color=green>[Firebase] Đăng ký thành công! Hãy kiểm tra trình duyệt (Firebase Console).</color>");
// }
// else
// {
// Debug.LogError("[Firebase] Đăng ký thất bại. Kiểm tra link URL hoặc Internet.");
// }
}
Debug.Log("<color=cyan>--- Firebase Test Finished ---</color>");
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: db205c30e8f41d84fa79269745feaf84

View File

@@ -1,112 +0,0 @@
using UnityEngine;
using UnityEngine.UIElements;
using PrimeTween;
using System.Threading.Tasks;
using DG.Tweening;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
namespace Baba_yaga.UI
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class HUDController : BaseUIController
{
private VisualElement _topLeft;
private VisualElement _bottomLeft;
private ProgressBar _healthBar;
private ProgressBar _staminaBar;
private float _lastActionTime;
private const float FADE_TIMEOUT = 5.0f;
private bool _isFaded = false;
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
{
base.Initialize(uxmlRoot, manager);
_topLeft = root.Q<VisualElement>("TopLeft");
_bottomLeft = root.Q<VisualElement>("BottomLeft");
_healthBar = root.Q<ProgressBar>("HealthBar");
_staminaBar = root.Q<ProgressBar>("StaminaBar");
if (LocalizationManager.Instance != null)
{
LocalizationManager.Instance.OnLanguageChanged += ApplyLocalization;
ApplyLocalization();
}
_lastActionTime = Time.time;
}
private void OnDestroy()
{
if (LocalizationManager.Instance != null)
{
LocalizationManager.Instance.OnLanguageChanged -= ApplyLocalization;
}
}
private void ApplyLocalization()
{
if (LocalizationManager.Instance == null) return;
root.Query<Label>().ForEach(l => {
if (l.text == "HEALTH") l.text = LocalizationManager.Instance.GetLocalizedString("HUD_HEALTH");
if (l.text == "STAMINA") l.text = LocalizationManager.Instance.GetLocalizedString("HUD_STAMINA");
if (l.text == "MINIMAP") l.text = LocalizationManager.Instance.GetLocalizedString("HUD_MINIMAP");
});
}
public void UpdateHUD(float health, float stamina)
{
_healthBar.value = health;
_staminaBar.value = stamina;
WakeUpHUD();
}
public void UpdateStats(int ping, int fps)
{
string pingPrefix = LocalizationManager.Instance != null ? LocalizationManager.Instance.GetLocalizedString("HUD_PING_PREFIX") : "PING: ";
string fpsPrefix = LocalizationManager.Instance != null ? LocalizationManager.Instance.GetLocalizedString("HUD_FPS_PREFIX") : "FPS: ";
root.Q<Label>("PingLabel").text = $"{pingPrefix}{ping}ms";
root.Q<Label>("FPSLabel").text = $"{fpsPrefix}{fps}";
}
public void WakeUpHUD()
{
_lastActionTime = Time.time;
/*if (_isFaded)
{
_isFaded = false;
Tween.Custom(_topLeft.style.opacity.value, 1f, duration: 0.3f, onValueChange: val => _topLeft.style.opacity = val);
Tween.Custom(_bottomLeft.style.opacity.value, 1f, duration: 0.3f, onValueChange: val => _bottomLeft.style.opacity = val);
}*/
}
public override void Update()
{
/*if (!_isFaded && Time.time - _lastActionTime > FADE_TIMEOUT)
{
_isFaded = true;
Tween.Custom(_topLeft.style.opacity.value, 0.2f, duration: 1.0f, onValueChange: val => _topLeft.style.opacity = val);
Tween.Custom(_bottomLeft.style.opacity.value, 0.2f, duration: 1.0f, onValueChange: val => _bottomLeft.style.opacity = val);
}*/
}
/*public override Task PlayTransitionIn()
{
Show();
_topLeft.style.opacity = 1;
_bottomLeft.style.opacity = 1;
return Task.CompletedTask;
}
public override Task PlayTransitionOut()
{
Hide();
return Task.CompletedTask;
}*/
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: e79b70607af6eeb458c8eb6605e39b56

View File

@@ -1,489 +0,0 @@
using UnityEngine;
using UnityEngine.UIElements;
using System.Collections.Generic;
using System.Threading.Tasks;
using Fusion;
using System.Linq;
namespace Baba_yaga.UI
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class LobbyController : BaseUIController
{
private VisualTreeAsset _roomItemTemplate;
private PlayerDataManager _playerDataManager;
private VisualElement _joinContainer, _createContainer, _loungeContainer, _passOverlay;
private TextField _roomIDInput, _roomNameInput, _roomPassInput;
private Toggle _passToggle;
private Label _createErrorLabel;
private Button _confirmCreateBtn;
private ScrollView _roomList;
private TextField _joinPassInput;
private Label _joinPassError;
private SessionInfo _selectedSession;
private Label _loungeRoomName;
private Button _readyBtn, _startBtn;
private Label _hostNameLabel, _hostStatusLabel;
private VisualElement _hostChatBox;
private Label _hostChatMessage;
private Label _guestNameLabel, _guestStatusLabel;
private VisualElement _guestChatBox;
private Label _guestChatMessage;
private TextField _chatInput;
private VisualElement _hostAvatar, _guestAvatar;
private VisualElement _transferHostOverlay;
private Button _confirmTransferBtn, _closeTransferBtn;
private PlayerRef _pendingTransferPlayer;
private bool _isBusy = false;
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
{
base.Initialize(uxmlRoot, manager);
_joinContainer = root.Q<VisualElement>("JoinContainer");
_createContainer = root.Q<VisualElement>("CreateContainer");
_loungeContainer = root.Q<VisualElement>("LoungeContainer");
_passOverlay = root.Q<VisualElement>("PasswordOverlay");
_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");
_roomList = root.Q<ScrollView>("RoomList");
_joinPassInput = root.Q<TextField>("JoinPassInput");
_joinPassError = root.Q<Label>("JoinPassError");
_loungeRoomName = root.Q<Label>("LoungeRoomName");
_readyBtn = root.Q<Button>("ReadyBtn");
_startBtn = root.Q<Button>("StartBtn");
if (_startBtn != null) _startBtn.style.display = DisplayStyle.None; // Default to hidden
_hostNameLabel = root.Q<Label>("HostName");
_hostStatusLabel = root.Q<Label>("HostReadyStatus");
_hostChatBox = root.Q<VisualElement>("HostChatBox");
_hostChatMessage = root.Q<Label>("HostChatMessage");
_guestNameLabel = root.Q<Label>("GuestName");
_guestStatusLabel = root.Q<Label>("GuestReadyStatus");
_guestChatBox = root.Q<VisualElement>("GuestChatBox");
_guestChatMessage = root.Q<Label>("GuestChatMessage");
_chatInput = root.Q<TextField>("ChatInput");
_hostAvatar = root.Q<VisualElement>("HostAvatar");
_guestAvatar = root.Q<VisualElement>("GuestAvatar");
_transferHostOverlay = root.Q<VisualElement>("TransferHostOverlay");
_confirmTransferBtn = root.Q<Button>("ConfirmTransferBtn");
_closeTransferBtn = root.Q<Button>("CloseTransferBtn");
root.Q<Button>("GoToCreateBtn").clicked += ShowCreate;
root.Q<Button>("CancelCreateBtn").clicked += ShowJoin;
/*root.Q<Button>("BackToMenuBtn").clicked += async () => { if (_isBusy) return; 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 (_hostAvatar != null) _hostAvatar.RegisterCallback<ClickEvent>(evt => OnAvatarClicked(true));
if (_guestAvatar != null) _guestAvatar.RegisterCallback<ClickEvent>(evt => OnAvatarClicked(false));
if (_confirmTransferBtn != null) _confirmTransferBtn.clicked += OnConfirmTransferHost;
if (_closeTransferBtn != null) _closeTransferBtn.clicked += () => { if(_transferHostOverlay != null) _transferHostOverlay.style.display = DisplayStyle.None; };
if (LocalizationManager.Instance != null) { LocalizationManager.Instance.OnLanguageChanged += ApplyLocalization; ApplyLocalization(); }
if (BasicSpawner.Instance != null) RegisterSpawnerEvents();
else 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; };
}
private void OnChatKeyDown(KeyDownEvent evt)
{
if (evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter)
{
evt.StopImmediatePropagation();
evt.PreventDefault();
string msg = _chatInput.value.Trim();
if (!string.IsNullOrEmpty(msg) && PlayerDataManager.Instance != null)
{
var runner = BasicSpawner.Instance.Runner;
if (runner != null) { PlayerDataManager.Instance.RPC_SendChatMessage(runner.LocalPlayer, msg); _chatInput.value = ""; _chatInput.Focus(); }
}
}
}
private void OnChatMessageReceived(PlayerRef sender, string message)
{
var runner = BasicSpawner.Instance.Runner;
if (runner == null) return;
var sortedPlayers = runner.ActivePlayers.OrderBy(p => p.PlayerId).ToList();
bool isHost = sortedPlayers.Count > 0 && sender == sortedPlayers[0];
if (isHost) ShowChatBubble(_hostChatBox, _hostChatMessage, message);
else ShowChatBubble(_guestChatBox, _guestChatMessage, message);
}
private async void ShowChatBubble(VisualElement box, Label label, string msg)
{
if (box == null || label == null) return;
label.text = msg;
box.style.display = DisplayStyle.Flex;
await Task.Delay(4000);
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()
{
_isBusy = false;
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;
var spawner = BasicSpawner.Instance;
if (spawner != null && (spawner.Runner == null || !spawner.Runner.IsRunning)) _ = spawner.StartLobby();
}
public void ShowCreate()
{
if (_joinContainer != null) _joinContainer.style.display = DisplayStyle.None;
if (_createContainer != null) _createContainer.style.display = DisplayStyle.Flex;
if (_createErrorLabel != null) _createErrorLabel.style.display = DisplayStyle.None;
if (_confirmCreateBtn != null) _confirmCreateBtn.SetEnabled(true);
if (_roomIDInput != null) _roomIDInput.value = "ROOM_" + Random.Range(1000, 9999).ToString();
}
private void ShowLounge(string 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 = roomName.ToUpper();
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") + spawner.Runner.SessionInfo.Name;
}
_playerDataManager = PlayerDataManager.Instance;
if (_playerDataManager != null) _playerDataManager.OnChatMessageReceived += OnChatMessageReceived;
}
private async void OnCreateRoomClicked()
{
if (_isBusy) return;
_isBusy = true;
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. Please re-enter the Lobby.");
_isBusy = false;
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);
}
finally
{
_isBusy = false;
if (_confirmCreateBtn != null) _confirmCreateBtn.SetEnabled(true);
}
}
private void ShowCreateError(string message)
{
if (_createErrorLabel != null) { _createErrorLabel.text = message; _createErrorLabel.style.display = DisplayStyle.Flex; }
if (_confirmCreateBtn != null) _confirmCreateBtn.SetEnabled(true);
}
private void UpdateRoomList(List<SessionInfo> sessions)
{
if (_roomList == null) return;
_roomList.Clear();
foreach (var session in sessions)
{
if (_roomItemTemplate == null) continue;
var item = _roomItemTemplate.Instantiate();
string displayName = session.Name;
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); }
_roomList.Add(item);
}
}
private async void OnRoomItemClicked(SessionInfo session)
{
if (_isBusy) return;
bool needsPass = session.Properties.ContainsKey("pw");
if (needsPass)
{
_selectedSession = session;
if (_passOverlay != null) _passOverlay.style.display = DisplayStyle.Flex;
if (_joinPassError != null) _joinPassError.style.display = DisplayStyle.None;
if (_joinPassInput != null) _joinPassInput.value = "";
}
else await JoinRoom(session.Name, null);
}
private async void OnConfirmPasswordClicked()
{
if (_isBusy || _selectedSession == null) return;
_isBusy = true;
string pass = _joinPassInput != null ? _joinPassInput.value : "";
if (_passOverlay != null) _passOverlay.style.display = DisplayStyle.None;
await JoinRoom(_selectedSession.Name, pass);
_isBusy = false;
}
private async Task JoinRoom(string sessionName, string password)
{
if (BasicSpawner.Instance != null)
{
if (await BasicSpawner.Instance.StartClient(sessionName, password)) ShowLounge(sessionName);
}
}
private void OnReadyClicked()
{
if (_isBusy) return;
var runner = BasicSpawner.Instance.Runner;
if (runner != null && _playerDataManager != null && _playerDataManager.TryGetPlayerMetaData(runner.LocalPlayer, out var myData))
_playerDataManager.RPC_SetReady(runner.LocalPlayer, !myData.IsReady);
}
private void OnStartClicked()
{
if (_isBusy) return;
BasicSpawner.Instance?.StartGame();
}
private void OnAvatarClicked(bool isHostSlot)
{
if (_playerDataManager == null || _playerDataManager.Leader != BasicSpawner.Instance.Runner.LocalPlayer) return;
var runner = BasicSpawner.Instance.Runner;
var sortedPlayers = runner.ActivePlayers.OrderBy(p => p.PlayerId).ToList();
PlayerRef clickedPlayer = PlayerRef.None;
if (isHostSlot && sortedPlayers.Count > 0) clickedPlayer = sortedPlayers[0];
else if (!isHostSlot && sortedPlayers.Count > 1) clickedPlayer = sortedPlayers[1];
if (clickedPlayer != PlayerRef.None && clickedPlayer != runner.LocalPlayer)
{
_pendingTransferPlayer = clickedPlayer;
if (_transferHostOverlay != null) _transferHostOverlay.style.display = DisplayStyle.Flex;
}
}
private void OnConfirmTransferHost()
{
if (_pendingTransferPlayer != PlayerRef.None && _playerDataManager != null)
{
_playerDataManager.RPC_TransferLeader(_pendingTransferPlayer);
if (_transferHostOverlay != null) _transferHostOverlay.style.display = DisplayStyle.None;
}
}
private async void OnLeaveLoungeClicked()
{
if (_isBusy) return;
_isBusy = true;
var runner = BasicSpawner.Instance.Runner;
if (runner != null) await runner.Shutdown(false);
if (_playerDataManager != null) _playerDataManager.OnChatMessageReceived -= OnChatMessageReceived;
ShowJoin();
_isBusy = false;
}
public override void Update() { if (_loungeContainer != null && _loungeContainer.style.display == DisplayStyle.Flex) UpdateLoungeUI(); }
private void UpdateLoungeUI()
{
var spawner = BasicSpawner.Instance;
if (spawner == null) return;
var runner = spawner.Runner;
if (runner == null) return;
// 1. PlayerDataManager Sync
if (_playerDataManager == null || _playerDataManager.Object == null || !_playerDataManager.Object.IsValid)
{
_playerDataManager = PlayerDataManager.Instance;
if (_playerDataManager != null)
{
_playerDataManager.OnChatMessageReceived += OnChatMessageReceived;
}
else return; // Still waiting for synchronization
}
// 2. Identify Players
var sortedPlayers = runner.ActivePlayers.OrderBy(p => p.PlayerId).ToList();
PlayerRef hostRef = sortedPlayers.Count > 0 ? sortedPlayers[0] : PlayerRef.None;
PlayerRef guestRef = sortedPlayers.Count > 1 ? sortedPlayers[1] : PlayerRef.None;
PlayerRef leaderRef = _playerDataManager.Leader;
// 3. Strict Visibility Check (Leader Only)
bool isLeader = runner.LocalPlayer == leaderRef;
if (_startBtn != null)
{
_startBtn.style.display = isLeader ? DisplayStyle.Flex : DisplayStyle.None;
}
if (runner.SessionInfo != null && runner.SessionInfo.Properties.TryGetValue("rn", out var rnProp)) _loungeRoomName.text = rnProp.ToString().ToUpper();
// Host Display
if (hostRef != PlayerRef.None && _playerDataManager.TryGetPlayerMetaData(hostRef, out var hostData))
{
_hostNameLabel.text = hostData.Name.ToString().ToUpper();
string readyStatus = hostData.IsReady ? GetT("LOBBY_READY") : GetT("LOBBY_NOT_READY");
string roleLabel = (hostRef == leaderRef) ? GetT("LOBBY_HOST_LABEL") : GetT("LOBBY_PLAYER_LABEL");
_hostStatusLabel.text = $"{roleLabel} - {readyStatus}";
_hostStatusLabel.style.color = hostData.IsReady ? Color.green : Color.red;
// Highlight leader avatar
if (_hostAvatar != null)
{
float width = (hostRef == leaderRef) ? 2f : 0f;
_hostAvatar.style.borderTopWidth = width;
_hostAvatar.style.borderBottomWidth = width;
_hostAvatar.style.borderLeftWidth = width;
_hostAvatar.style.borderRightWidth = width;
}
}
else { _hostNameLabel.text = GetT("LOBBY_SYNCING"); _hostStatusLabel.text = "-"; }
// Guest Display
if (guestRef != PlayerRef.None && _playerDataManager.TryGetPlayerMetaData(guestRef, out var guestData))
{
_guestNameLabel.text = guestData.Name.ToString().ToUpper();
string readyStatus = guestData.IsReady ? GetT("LOBBY_READY") : GetT("LOBBY_NOT_READY");
string roleLabel = (guestRef == leaderRef) ? GetT("LOBBY_HOST_LABEL") : GetT("LOBBY_PLAYER_LABEL");
_guestStatusLabel.text = $"{roleLabel} - {readyStatus}";
_guestStatusLabel.style.color = guestData.IsReady ? Color.green : Color.red;
// Highlight leader avatar
if (_guestAvatar != null)
{
float width = (guestRef == leaderRef) ? 2f : 0f;
_guestAvatar.style.borderTopWidth = width;
_guestAvatar.style.borderBottomWidth = width;
_guestAvatar.style.borderLeftWidth = width;
_guestAvatar.style.borderRightWidth = width;
_guestAvatar.style.borderTopColor = Color.white;
_guestAvatar.style.borderBottomColor = Color.white;
_guestAvatar.style.borderLeftColor = Color.white;
_guestAvatar.style.borderRightColor = Color.white;
}
}
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;
if (_guestAvatar != null)
{
_guestAvatar.style.borderTopWidth = 0;
_guestAvatar.style.borderBottomWidth = 0;
_guestAvatar.style.borderLeftWidth = 0;
_guestAvatar.style.borderRightWidth = 0;
}
}
// 4. Start Button Logic (Leader Only)
if (_startBtn != null && isLeader)
{
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;
}
bool canStart = allReady && playerCount >= 2;
_startBtn.SetEnabled(canStart);
_startBtn.text = GetT("LOBBY_START_BTN");
if (canStart)
{
_startBtn.style.backgroundColor = new StyleColor(Color.green);
_startBtn.style.color = new StyleColor(Color.black);
}
else
{
_startBtn.style.backgroundColor = new StyleColor(new Color(0.2f, 0.2f, 0.2f, 0.8f));
_startBtn.style.color = new StyleColor(new Color(1f, 1f, 1f, 0.5f));
}
}
// Ready Button Logic (Everyone)
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);
}
}
}
}
private async void Invoke(string methodName, float delay) { await Task.Delay((int)(delay * 1000)); if (methodName == nameof(RegisterSpawnerEvents)) RegisterSpawnerEvents(); }
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 9c37c552a9c18a242bcc8860a0a5212f

View File

@@ -1,87 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
namespace Baba_yaga.UI
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class LocalizationManager : MonoBehaviour
{
public static LocalizationManager Instance { get; private set; }
private Dictionary<string, string> _localizedText = new Dictionary<string, string>();
private string _currentLanguage = "en";
public event Action OnLanguageChanged;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
// Đọc ngôn ngữ đã lưu hoặc mặc định là tiếng Anh
string savedLang = PlayerPrefs.GetString("Language", "en");
LoadLanguage(savedLang);
}
else
{
Destroy(gameObject);
}
}
public void LoadLanguage(string langCode)
{
_currentLanguage = langCode;
TextAsset jsonAsset = Resources.Load<TextAsset>($"Localization/{langCode}");
if (jsonAsset != null)
{
ParseJsonRobust(jsonAsset.text);
PlayerPrefs.SetString("Language", langCode);
PlayerPrefs.Save();
// Thông báo cho các UI khác biết ngôn ngữ đã đổi
OnLanguageChanged?.Invoke();
Debug.Log($"[Localization] Successfully loaded language: {langCode} ({_localizedText.Count} keys)");
}
else
{
Debug.LogError($"[Localization] Language file NOT FOUND in Resources/Localization/{langCode}");
}
}
// Dùng Regex để bóc tách Key-Value từ JSON cực kỳ chính xác
private void ParseJsonRobust(string json)
{
_localizedText.Clear();
// Regex này sẽ tìm tất cả các cặp "key" : "value" bất kể khoảng trắng hay xuống dòng
MatchCollection matches = Regex.Matches(json, "\"([^\"]+)\"\\s*:\\s*\"([^\"]+)\"");
foreach (Match match in matches)
{
if (match.Groups.Count == 3)
{
string key = match.Groups[1].Value;
string value = match.Groups[2].Value;
_localizedText[key] = value;
}
}
}
public string GetLocalizedString(string key)
{
if (_localizedText.TryGetValue(key, out string value))
{
return value;
}
return key; // Trả về chính key nếu không tìm thấy dịch thuật
}
public string CurrentLanguage => _currentLanguage;
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: ff7ac0ce8c8c98445b895ac53a4618f1

View File

@@ -1,119 +0,0 @@
using UnityEngine;
using UnityEngine.UIElements;
using PrimeTween;
using System.Threading.Tasks;
using DG.Tweening;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
namespace Baba_yaga.UI
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
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;
*/
// Đăng ký Localization
if (LocalizationManager.Instance != null)
{
LocalizationManager.Instance.OnLanguageChanged += ApplyLocalization;
}
ApplyLocalization();
}
private void ApplyLocalization()
{
if (LocalizationManager.Instance == null) return;
var title = root.Q<Label>(className: "text-heading");
if (title != null) title.text = LocalizationManager.Instance.GetLocalizedString("LOGIN_TITLE");
if (_nameInput != null) _nameInput.label = LocalizationManager.Instance.GetLocalizedString("LOGIN_USER");
if (_confirmBtn != null) _confirmBtn.text = LocalizationManager.Instance.GetLocalizedString("LOGIN_BTN");
var guestBtn = root.Q<Button>("GuestBtn");
if (guestBtn != null) guestBtn.text = LocalizationManager.Instance.GetLocalizedString("LOGIN_GUEST");
}
/*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 Tween.Custom(0f, 1f, duration: 0.5f, onValueChange: val => root.style.opacity = val);
}*/
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: fbd606c21d317da47820446e4da1c55b

View File

@@ -1,309 +0,0 @@
using UnityEngine;
using UnityEngine.UIElements;
using PrimeTween;
using System.Threading.Tasks;
using DG.Tweening;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
namespace Baba_yaga.UI
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class MainMenuController : BaseUIController
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public enum MenuState { Idle, Ribbon }
private MenuState _currentState = MenuState.Idle;
private VisualElement _logo;
private VisualElement _ribbon;
private VisualElement _logoSpace;
private float _lastInteractionTime;
private const float IDLE_TIMEOUT = 5.0f;
private bool _isFirstLoad = true;
private Tween _pulseTween;
private Tween _rotationTween;
private Texture2D _currentIcon;
private bool _isBusy = false;
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
{
base.Initialize(uxmlRoot, manager);
_logo = root.Q<VisualElement>("Logo");
_ribbon = root.Q<VisualElement>("Ribbon");
_logoSpace = root.Q<VisualElement>("LogoSpace");
if (_logo == null)
{
Debug.LogError($"[MainMenuController] Element 'Logo' not found in UXML!");
return;
}
// Lắng nghe sự kiện thay đổi kích thước toàn màn hình
root.RegisterCallback<GeometryChangedEvent>(OnScreenResize);
/*_logo.RegisterCallback<ClickEvent>(OnLogoClicked);*/
var settingsBtn = root.Q<Button>("SettingsBtn");
/*if (settingsBtn != null) settingsBtn.clicked += () => { if (_isBusy) return; uiManager.ToggleSettings(); };
root.Q<Button>("JoinBtn").clicked += async () => { if (_isBusy) return; _isBusy = true; await uiManager.Push<LobbyController>(); };
root.Q<Button>("CreateBtn").clicked += async () => { if (_isBusy) return; _isBusy = true; await uiManager.Push<LobbyController>(); };
root.Q<Button>("ProfileBtn").clicked += async () => { if (_isBusy) return; _isBusy = true; await uiManager.Push<ProfileController>(); };
root.Q<Button>("ExitBtn").clicked += () => Application.Quit();*/
// Đăng ký Localization
if (LocalizationManager.Instance != null)
{
LocalizationManager.Instance.OnLanguageChanged += ApplyLocalization;
}
ApplyLocalization();
ResetLogoPosition();
StartPulse();
_lastInteractionTime = Time.time;
}
private void ApplyLocalization()
{
if (LocalizationManager.Instance == null) return;
var joinBtn = root.Q<Button>("JoinBtn");
if (joinBtn != null) joinBtn.text = LocalizationManager.Instance.GetLocalizedString("MENU_JOIN");
var createBtn = root.Q<Button>("CreateBtn");
if (createBtn != null) createBtn.text = LocalizationManager.Instance.GetLocalizedString("MENU_CREATE");
var settingsBtn = root.Q<Button>("SettingsBtn");
if (settingsBtn != null) settingsBtn.text = LocalizationManager.Instance.GetLocalizedString("MENU_SETTINGS");
var profileBtn = root.Q<Button>("ProfileBtn");
if (profileBtn != null) profileBtn.text = LocalizationManager.Instance.GetLocalizedString("MENU_PROFILE");
var exitBtn = root.Q<Button>("ExitBtn");
if (exitBtn != null) exitBtn.text = LocalizationManager.Instance.GetLocalizedString("MENU_EXIT");
var playLabel = _logo.Q<Label>();
if (playLabel != null) playLabel.text = LocalizationManager.Instance.GetLocalizedString("MENU_PLAY");
}
private void OnScreenResize(GeometryChangedEvent evt)
{
// Khi màn hình thay đổi kích thước, nếu đang ở Ribbon thì cập nhật theo LogoSpace
if (_currentState == MenuState.Ribbon)
{
UpdateLogoToSpace();
}
else
{
ResetLogoPosition();
}
}
private void ResetLogoPosition()
{
if (_logo == null) return;
// Sử dụng phần trăm để luôn ở giữa bất kể độ phân giải
_logo.style.left = Length.Percent(50);
_logo.style.top = Length.Percent(50);
_logo.style.translate = new StyleTranslate(new Translate(Length.Percent(-50), Length.Percent(-50)));
_logo.style.width = 200;
_logo.style.height = 200;
}
public void SetGameIcon(Texture2D icon)
{
if (icon == null || _logo == null) return;
_currentIcon = icon;
_logo.style.backgroundImage = icon;
var radius = new StyleLength(new Length(50, LengthUnit.Percent));
_logo.style.borderTopLeftRadius = radius;
_logo.style.borderTopRightRadius = radius;
_logo.style.borderBottomLeftRadius = radius;
_logo.style.borderBottomRightRadius = radius;
_logo.style.overflow = Overflow.Hidden;
var label = _logo.Q<Label>();
if (label != null) label.style.display = DisplayStyle.None;
StartRotation();
}
private void StartRotation()
{
/*if (_currentIcon == null) return;
if (_rotationTween.isAlive) _rotationTween.Stop();
_rotationTween = Tween.Custom(0f, 360f, duration: 4f,
onValueChange: val => _logo.style.rotate = new StyleRotate(new Rotate(Angle.Degrees(val))),
cycles: -1,
ease: Ease.Linear);*/
}
/*public override async Task PlayTransitionIn()
{
_isBusy = false;
_lastInteractionTime = Time.time;
_currentState = MenuState.Idle;
ResetLogoPosition();
if (_ribbon != null)
{
_ribbon.style.display = DisplayStyle.None;
_ribbon.style.opacity = 0;
}
StartRotation();
await base.PlayTransitionIn();
if (!_isFirstLoad) TransitionToRibbon();
else _isFirstLoad = false;
}
public override async Task PlayTransitionOut()
{
/*if (_rotationTween.isAlive) _rotationTween.Stop();
await base.PlayTransitionOut();#1#
}*/
/*private async void OnLogoClicked(ClickEvent evt)
{
if (_isBusy) return;
_lastInteractionTime = Time.time;
if (_currentState == MenuState.Idle) TransitionToRibbon();
else
{
_isBusy = true;
await uiManager.Push<LobbyController>();
}
}*/
private void TransitionToRibbon()
{
if (_currentState == MenuState.Ribbon && _ribbon.resolvedStyle.display == DisplayStyle.Flex) return;
_currentState = MenuState.Ribbon;
_lastInteractionTime = Time.time;
_ribbon.style.display = DisplayStyle.Flex;
/*
Tween.Custom(0f, 1f, duration: 0.3f, onValueChange: val => _ribbon.style.opacity = val);
*/
// Đợi một frame để Ribbon layout xong rồi mới lấy vị trí LogoSpace
_logoSpace.RegisterCallback<GeometryChangedEvent>(OnLogoSpaceReady);
}
private void OnLogoSpaceReady(GeometryChangedEvent evt)
{
_logoSpace.UnregisterCallback<GeometryChangedEvent>(OnLogoSpaceReady);
UpdateLogoToSpace(true);
}
private void UpdateLogoToSpace(bool animate = false)
{
Rect targetBounds = _logoSpace.worldBound;
if (targetBounds.width <= 0) return;
// Chuyển đổi tọa độ world của LogoSpace sang tọa độ local của root
Vector2 localPos = root.WorldToLocal(new Vector2(targetBounds.x, targetBounds.y));
float targetX = localPos.x + (targetBounds.width / 2f);
float targetY = localPos.y + (targetBounds.height / 2f);
// Khi ở Ribbon, chúng ta bỏ translate -50% để tính toán chính xác tâm
_logo.style.translate = new StyleTranslate(new Translate(Length.Percent(-50), Length.Percent(-50)));
if (animate)
{
/*Tween.Custom(_logo.resolvedStyle.left, targetX, duration: 0.5f,
onValueChange: val => _logo.style.left = val,
ease: Ease.OutQuad);
Tween.Custom(_logo.resolvedStyle.top, targetY, duration: 0.5f,
onValueChange: val => _logo.style.top = val,
ease: Ease.OutQuad);
Tween.Custom(_logo.resolvedStyle.width, 100f, duration: 0.5f,
onValueChange: val => _logo.style.width = val,
ease: Ease.OutQuad);
Tween.Custom(_logo.resolvedStyle.height, 100f, duration: 0.5f,
onValueChange: val => _logo.style.height = val,
ease: Ease.OutQuad);*/
}
else
{
_logo.style.left = targetX;
_logo.style.top = targetY;
_logo.style.width = 100;
_logo.style.height = 100;
}
_lastInteractionTime = Time.time;
}
private void TransitionToIdle()
{
if (_currentState == MenuState.Idle) return;
_currentState = MenuState.Idle;
// Quay lại dùng phần trăm để tự động căn giữa
/*Tween.Custom(_logo.resolvedStyle.width, 200f, duration: 0.5f, onValueChange: val => _logo.style.width = val, ease: Ease.OutQuad);
Tween.Custom(_logo.resolvedStyle.height, 200f, duration: 0.5f, onValueChange: val => _logo.style.height = val, ease: Ease.OutQuad);
// Animate left/top về 50%
float startLeft = _logo.resolvedStyle.left;
float startTop = _logo.resolvedStyle.top;
float targetLeft = root.resolvedStyle.width / 2f;
float targetTop = root.resolvedStyle.height / 2f;
Tween.Custom(0f, 1f, duration: 0.5f, ease: Ease.OutQuad, onValueChange: t => {
_logo.style.left = Mathf.Lerp(startLeft, targetLeft, t);
_logo.style.top = Mathf.Lerp(startTop, targetTop, t);
}).OnComplete(() => {
ResetLogoPosition(); // Đảm bảo cuối cùng dùng đơn vị Percent
});
Tween.Custom(1f, 0f, duration: 0.5f, onValueChange: val => _ribbon.style.opacity = val)
.OnComplete(() => _ribbon.style.display = DisplayStyle.None);*/
}
public override void Update()
{
if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0 || Input.anyKey)
{
_lastInteractionTime = Time.time;
}
if (_currentState == MenuState.Ribbon && Time.time - _lastInteractionTime > IDLE_TIMEOUT)
{
TransitionToIdle();
}
}
private void StartPulse()
{
/*if (_pulseTween.isAlive) _pulseTween.Stop();
_pulseTween = Tween.Custom(Vector3.one, Vector3.one * 1.1f, duration: 0.8f,
onValueChange: val => _logo.style.scale = new StyleScale(new Scale(val)),
cycles: -1,
cycleMode: CycleMode.Yoyo,
ease: Ease.InOutSine);*/
}
private void OnDestroy()
{
if (LocalizationManager.Instance != null)
{
LocalizationManager.Instance.OnLanguageChanged -= ApplyLocalization;
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 691980524acfc544f9660cfc35ce3616

View File

@@ -1,44 +0,0 @@
using UnityEngine;
using System.Collections.Generic;
namespace Baba_yaga.UI
{
public static class MouseMetricsHelper
{
private static int _reportCount = 0;
private static float _timer = 0f;
private static int _lastPollingRate = 0;
private static float _lastLatency = 0f;
private static Vector2 _lastMousePos;
public static (int pollingRate, float latencyMs) GetMetrics()
{
Update();
return (_lastPollingRate, _lastLatency);
}
private static void Update()
{
_timer += Time.unscaledDeltaTime;
// Count "reports" based on position changes (simulated polling rate)
Vector2 currentPos = Input.mousePosition;
if (currentPos != _lastMousePos)
{
_reportCount++;
_lastMousePos = currentPos;
}
if (_timer >= 1f)
{
_lastPollingRate = (int)(_reportCount / _timer);
_reportCount = 0;
_timer = 0f;
}
// Dummy latency simulation (Input System doesn't expose raw hardware latency easily)
// In a real scenario, this would involve timestamping HID reports
_lastLatency = (1.0f / (Screen.currentResolution.refreshRateRatio.value > 0 ? (float)Screen.currentResolution.refreshRateRatio.value : 60f)) * 1000f;
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: ff50ca9a6ee819b48b273986e55f2772

View File

@@ -1,77 +0,0 @@
using UnityEngine.UIElements;
using System.Threading.Tasks;
using Baba_yaga;
using UnityEngine;
namespace Baba_yaga.UI
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class PauseMenuController : BaseUIController
{
private Button _resumeBtn;
private Button _quitBtn;
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
{
base.Initialize(uxmlRoot, manager);
_resumeBtn = root.Q<Button>("ResumeBtn");
_quitBtn = root.Q<Button>("QuitBtn");
/*if (_resumeBtn != null) _resumeBtn.clicked += OnResumeClicked;*/
if (_quitBtn != null) _quitBtn.clicked += OnQuitClicked;
ApplyLocalization();
if (LocalizationManager.Instance != null)
LocalizationManager.Instance.OnLanguageChanged += ApplyLocalization;
}
private void OnDestroy()
{
if (LocalizationManager.Instance != null)
LocalizationManager.Instance.OnLanguageChanged -= ApplyLocalization;
}
private void ApplyLocalization()
{
if (_resumeBtn != null) _resumeBtn.text = GetLoc("PAUSE_RESUME");
if (_quitBtn != null) _quitBtn.text = GetLoc("PAUSE_QUIT");
var title = root.Q<Label>("PauseTitle");
if (title != null) title.text = GetLoc("PAUSE_TITLE");
}
/*private void OnResumeClicked()
{
uiManager.TogglePauseMenu();
}*/
private void OnQuitClicked()
{
Debug.Log("[PauseMenu] Quit clicked - shutting down runner.");
/*if (BasicSpawner.Instance != null && BasicSpawner.Instance.Runner != null)
{
BasicSpawner.Instance.Runner.Shutdown();
}
else
{
uiManager.OnBackToMenu();
}*/
}
/*public override async Task PlayTransitionIn()
{
/*Show();
root.style.opacity = 0;
await PrimeTween.Tween.Custom(0f, 1f, duration: 0.2f, onValueChange: val => root.style.opacity = val);
await Task.Delay(200);#1#
}
public override async Task PlayTransitionOut()
{
/*await PrimeTween.Tween.Custom(1f, 0f, duration: 0.2f, onValueChange: val => root.style.opacity = val);
await Task.Delay(200);
Hide();#1#
}*/
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: a8be766526476e44ea7c5e19567f2568

View File

@@ -1,98 +0,0 @@
using UnityEngine;
using UnityEngine.UIElements;
using Fusion;
namespace Baba_yaga.UI
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class PerformanceOverlay : MonoBehaviour
{
private static PerformanceOverlay _instance;
private Label _fpsLabel;
private UIDocument _uiDocument;
private VisualElement _root;
private float _deltaTime = 0f;
private bool _isVisible = false;
public static void SetVisible(bool visible)
{
if (_instance == null && visible)
{
var go = new GameObject("PerformanceOverlay");
_instance = go.AddComponent<PerformanceOverlay>();
DontDestroyOnLoad(go);
}
if (_instance != null)
{
_instance._isVisible = visible;
if (_instance._root != null)
{
_instance._root.style.display = visible ? DisplayStyle.Flex : DisplayStyle.None;
}
}
}
private void Awake()
{
_uiDocument = gameObject.AddComponent<UIDocument>();
// Đặt thứ tự hiển thị cực cao để luôn nằm trên cùng
_uiDocument.sortingOrder = 999;
// Thử lấy PanelSettings từ UIManager để đồng bộ tỉ lệ scale
if (UIManager.Instance != null && UIManager.Instance.GetComponent<UIDocument>() != null)
{
_uiDocument.panelSettings = UIManager.Instance.GetComponent<UIDocument>().panelSettings;
}
_root = new VisualElement();
_root.style.position = Position.Absolute;
_root.style.bottom = 15;
_root.style.right = 15;
_root.pickingMode = PickingMode.Ignore;
_fpsLabel = new Label("0 FPS | 0.0ms | PING: 0ms");
_fpsLabel.pickingMode = PickingMode.Ignore;
_fpsLabel.style.color = Color.white;
_fpsLabel.style.fontSize = 12;
_fpsLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
// Shadow effect
_fpsLabel.style.textShadow = new TextShadow { offset = new Vector2(1, 1), blurRadius = 1, color = Color.black };
_root.Add(_fpsLabel);
_uiDocument.rootVisualElement.Add(_root);
_root.style.display = _isVisible ? DisplayStyle.Flex : DisplayStyle.None;
}
private void Update()
{
if (!_isVisible) return;
_deltaTime += (Time.unscaledDeltaTime - _deltaTime) * 0.1f;
float fps = 1.0f / _deltaTime;
float ms = _deltaTime * 1000.0f;
int ping = 0;
if (BasicSpawner.Instance != null && BasicSpawner.Instance.Runner != null && BasicSpawner.Instance.Runner.IsRunning)
{
var runner = BasicSpawner.Instance.Runner;
if (runner.LocalPlayer != PlayerRef.None)
{
ping = (int)(runner.GetPlayerRtt(runner.LocalPlayer) * 1000);
}
}
var (_, deviceLatency) = MouseMetricsHelper.GetMetrics();
_fpsLabel.text = $"{Mathf.Ceil(fps)} FPS | {ms:F1}ms | LATENCY: {deviceLatency:F0}ms | PING: {ping}ms";
// Color coding based on performance
if (fps < 30) _fpsLabel.style.color = Color.red;
else if (fps < 55) _fpsLabel.style.color = Color.yellow;
else _fpsLabel.style.color = Color.green;
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 7e018e7d76dda004e89cd989a7413168

View File

@@ -1,135 +0,0 @@
using UnityEngine;
using UnityEngine.UIElements;
using System.Threading.Tasks;
using Baba_yaga.Game;
using Baba_yaga.UI;
namespace Baba_yaga.UI
{
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class ProfileController : BaseUIController
{
private Label _username;
private Label _rank;
private Label _eloLabel;
private ProgressBar _winRateBar;
private Label _winRateText;
private Button _logoutBtn;
// Future authentication schema placeholders
private string _googleIdPlaceholder = "";
private string _avatarUrlPlaceholder = "";
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
{
base.Initialize(uxmlRoot, manager);
_username = root.Q<Label>("Username");
_rank = root.Q<Label>("Rank");
_eloLabel = root.Q<Label>("EloLabel");
_winRateBar = root.Q<ProgressBar>("WinRateBar");
_winRateText = root.Q<Label>("WinRateText");
_logoutBtn = root.Q<Button>("LogoutBtn");
/*root.Q<Button>("BackBtn").clicked += async () => await uiManager.Pop();*/
/*if (_logoutBtn != null)
{
_logoutBtn.clicked += Logout;
}*/
if (LocalizationManager.Instance != null)
{
LocalizationManager.Instance.OnLanguageChanged += ApplyLocalization;
ApplyLocalization();
}
LoadProfileData();
}
private void OnDestroy()
{
if (LocalizationManager.Instance != null)
{
LocalizationManager.Instance.OnLanguageChanged -= ApplyLocalization;
}
}
private void ApplyLocalization()
{
if (LocalizationManager.Instance == null) return;
root.Query<Label>().ForEach(l => {
if (l.text == "WIN RATE") l.text = LocalizationManager.Instance.GetLocalizedString("PROFILE_WIN_RATE");
if (l.text == "INVENTORY") l.text = LocalizationManager.Instance.GetLocalizedString("PROFILE_INVENTORY");
});
var backBtn = root.Q<Button>("BackBtn");
if (backBtn != null) backBtn.text = LocalizationManager.Instance.GetLocalizedString("PROFILE_BACK");
if (_logoutBtn != null) _logoutBtn.text = LocalizationManager.Instance.GetLocalizedString("PROFILE_LOGOUT");
}
/*public override async Task PlayTransitionIn()
{
await LoadProfileData(); // Refresh data every time we show the profile
await base.PlayTransitionIn();
}*/
private async Task LoadProfileData()
{
// Load saved username or fallback
string savedName = PlayerPrefs.GetString("Username", "Unknown Player");
_username.text = savedName.ToUpper();
// Future schema mockup (Google Sign-In)
_googleIdPlaceholder = PlayerPrefs.GetString("GoogleID", "NOT_LINKED");
_avatarUrlPlaceholder = PlayerPrefs.GetString("AvatarURL", "");
// Fetch real Elo data
var eloData = await FirebaseService.GetPlayerData(savedName);
if (_eloLabel != null) _eloLabel.text = eloData.Rating.ToString();
if (_rank != null)
{
_rank.text = EloSystem.GetRank(eloData.Rating).ToUpper();
if (ColorUtility.TryParseHtmlString(EloSystem.GetRankColor(eloData.Rating), out Color rankColor))
{
_rank.style.color = rankColor;
}
}
// Calculate Win Rate from GamesPlayed (requires adding wins to schema, but for now we use mock/partial)
if (eloData.GamesPlayed > 0)
{
// Note: To show a real winrate, we'd need to store 'Wins' in PlayerEloData.
// For now, keeping the mock or setting a placeholder.
_winRateText.text = "CALCULATING...";
}
}
/*private async void Logout()
{
// Clear local save data
PlayerPrefs.DeleteKey("Username");
PlayerPrefs.DeleteKey("GoogleID");
PlayerPrefs.DeleteKey("AvatarURL");
PlayerPrefs.Save();
Debug.Log("[Profile] User logged out.");
// Disconnect from network if currently running
var runner = Object.FindFirstObjectByType<Fusion.NetworkRunner>();
if (runner != null && runner.IsRunning)
{
await runner.Shutdown();
}
// Redirect to Login Screen
await uiManager.Push<LoginController>();
}*/
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: fdea16b110511ef45889ed832b63560b

View File

@@ -1,612 +0,0 @@
// using UnityEngine;
// using UnityEngine.UIElements;
// using UnityEngine.Audio;
// using UnityEngine.InputSystem;
// using System.Collections.Generic;
// using System.Linq;
// using System;
// using System.Threading.Tasks;
// using DG.Tweening;
// using Baba_yaga;
// using PrimeTween;
// using Tween = PrimeTween.Tween;
// using Ease = PrimeTween.Ease;
//
// namespace Baba_yaga.UI
// {
// [UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class SettingsController : BaseUIController
// {
// private VisualElement _sidebar;
// private VisualElement _tabsColumn;
// private Label _tabTitle;
// private ScrollView _content;
// private Dictionary<string, Button> _tabButtons = new Dictionary<string, Button>();
// private string _activeTab = "GENERAL";
//
// private Tween _hoverTimer;
// private bool _isExpanded;
//
// // Osu Style Scroll Tracking
// private readonly Dictionary<string, VisualElement> _sectionHeaders = new Dictionary<string, VisualElement>();
// private bool _isManualScrolling;
//
// // Advanced Mouse Metrics
// private Label _mouseMetricsLabel;
//
// // FPS State
// private bool _fpsVisible;
//
// // Hover Tracking for Arrow Key Slider Control
// private Slider _hoveredSlider;
// private Action<float> _hoveredOnChanged;
// private float _sliderMin, _sliderMax;
//
// // Audio Slider Tracking for Sync
// private readonly Dictionary<string, (Slider slider, TextField input)> _audioSliders = new Dictionary<string, (Slider slider, TextField input)>();
//
// // Osu-style Volume Overlay
// private VisualElement _volumeContainer;
// private VisualElement _masterRing;
// private Label _masterVolLabel;
// private Dictionary<string, (VisualElement ring, Label label)> _subRings = new Dictionary<string, (VisualElement, Label)>();
// private string _hoveredSubVolume = null;
// private float _masterVol = 80f;
// private int _overlayActiveCount = 0;
//
// /*public override void Initialize(VisualElement uxmlRoot, UIManager manager)
// {
// base.Initialize(uxmlRoot, manager);
//
// _sidebar = root.Q<VisualElement>("Sidebar");
// _tabsColumn = root.Q<VisualElement>("TabsColumn");
// _tabTitle = root.Q<Label>("TabTitle");
// _content = root.Q<ScrollView>("SettingsContent");
//
// // Smart Sidebar Hover Logic
// _tabsColumn.RegisterCallback<PointerEnterEvent>(OnSidebarPointerEnter);
// _tabsColumn.RegisterCallback<PointerLeaveEvent>(OnSidebarPointerLeave);
//
// // Scroll Tracking cho Osu Style
// _content.verticalScroller.valueChanged += OnScrollValueChanged;
//
// // Đăng ký sự kiện đổi ngôn ngữ
// if (LocalizationManager.Instance != null)
// {
// LocalizationManager.Instance.OnLanguageChanged += OnLanguageChanged;
// }
//
// // Global Volume Catch
// uiManager.Root.RegisterCallback<WheelEvent>(OnMouseWheel, TrickleDown.TrickleDown);
// SetupHierarchicalVolumeOverlay();
//
// root.RegisterCallback<PointerDownEvent>(evt => {
// if (evt.target == root) uiManager.ToggleSettings();
// });
//
// root.RegisterCallback<KeyDownEvent>(OnKeyDown);
//
// SetupTab("GeneralTab", "GENERAL");
// SetupTab("VideoTab", "VIDEO");
// SetupTab("SoundTab", "SOUND");
// SetupTab("ControlTab", "CONTROL");
//
// var closeBtn = root.Q<Button>("CloseSettingsBtn");
// if (closeBtn != null) closeBtn.clicked += () => uiManager.ToggleSettings();
//
// _masterVol = PlayerPrefs.GetFloat("MasterVolume", 80f);
//
// // Render ban đầu
// RefreshUI();
// ApplyVideoSettings();
// }*/
//
// private void OnLanguageChanged()
// {
// // Lưu lại vị trí cuộn hiện tại
// float currentScroll = _content.scrollOffset.y;
// RefreshUI();
// // Khôi phục vị trí cuộn sau một frame để layout kịp cập nhật
// _content.schedule.Execute(() => _content.scrollOffset = new Vector2(0, currentScroll)).StartingIn(10);
// }
//
// private void RefreshUI()
// {
// RenderAllSettings();
// UpdateTabLabels();
// HighlightTab(_activeTab);
// }
//
// private void UpdateTabLabels()
// {
// foreach (var kvp in _tabButtons)
// {
// var label = kvp.Value.Q<Label>(className: "tab-label");
// if (label != null) label.text = GetT(kvp.Key);
// }
// }
//
// private string GetT(string key) => LocalizationManager.Instance != null ? LocalizationManager.Instance.GetLocalizedString(key) : key;
//
// private void OnSidebarPointerEnter(PointerEnterEvent evt)
// {
// /*_hoverTimer.Stop();
// ExpandSidebar();*/
// }
//
// private void OnSidebarPointerLeave(PointerLeaveEvent evt)
// {
// /*_hoverTimer.Stop();
// CollapseSidebar();*/
// }
//
// /*private void ExpandSidebar()
// {
// if (_isExpanded) return;
// _isExpanded = true;
// _tabsColumn.AddToClassList("sidebar-expanded");
// Tween.Custom(_tabsColumn.resolvedStyle.width, 240f, duration: 0.5f, ease: Ease.OutQuart, onValueChange: val => _tabsColumn.style.width = val);
// }*/
//
// /*rivate void CollapseSidebar()
// {
// if (!_isExpanded) return;
// _isExpanded = false;
// _tabsColumn.RemoveFromClassList("sidebar-expanded");
// Tween.Custom(_tabsColumn.resolvedStyle.width, 80f, duration: 0.45f, ease: Ease.OutQuart, onValueChange: val => _tabsColumn.style.width = val);
// }*/
//
// private void RenderAllSettings()
// {
// _content.Clear();
// _sectionHeaders.Clear();
//
// RenderGeneralTab();
// RenderVideoTab();
// RenderSoundTab();
// RenderControlTab();
//
// // Thêm khoảng trống cuối để cuộn thoải mái
// var spacer = new VisualElement { style = { height = 200 } };
// _content.Add(spacer);
// }
//
// private void SetupTab(string btnName, string tabId)
// {
// var btn = root.Q<Button>(btnName);
// if (btn != null)
// {
// _tabButtons[tabId] = btn;
// btn.clicked += () => ScrollToSection(tabId);
// }
// }
//
// private void ScrollToSection(string tabId)
// {
// if (!_sectionHeaders.TryGetValue(tabId, out var header)) return;
//
// _isManualScrolling = true;
// HighlightTab(tabId);
//
// float targetY = header.layout.y;
// /*Tween.Custom(_content.scrollOffset.y, targetY, duration: 0.5f, ease: Ease.OutQuart, onValueChange: val => {
// _content.scrollOffset = new Vector2(0, val);
// }).OnComplete(() => _isManualScrolling = false);*/
// }
//
// private void OnScrollValueChanged(float val)
// {
// if (_isManualScrolling) return;
//
// string currentActive = "GENERAL";
// float minDistance = float.MaxValue;
//
// foreach (var kvp in _sectionHeaders)
// {
// float dist = Math.Abs(kvp.Value.worldBound.y - _content.worldBound.y);
// if (dist < minDistance)
// {
// minDistance = dist;
// currentActive = kvp.Key;
// }
// }
//
// if (_activeTab != currentActive) HighlightTab(currentActive);
// }
//
// private void HighlightTab(string tabId)
// {
// _activeTab = tabId;
// _tabTitle.text = GetT(tabId);
// foreach (var kvp in _tabButtons)
// {
// if (kvp.Key == tabId) kvp.Value.AddToClassList("active-tab");
// else kvp.Value.RemoveFromClassList("active-tab");
// }
// }
//
// private void RenderGeneralTab()
// {
// var header = CreateSection("GENERAL");
// _sectionHeaders["GENERAL"] = header;
// _content.Add(header);
//
// _content.Add(CreateSubSection("ACCOUNT"));
// var userRow = new VisualElement { style = { flexDirection = FlexDirection.Row, alignItems = Align.Center, marginBottom = 10 } };
// var loggedInLabel = new Label(GetT("LOGGED_IN_AS")); loggedInLabel.AddToClassList("text-body");
// userRow.Add(loggedInLabel);
// userRow.Add(new Label(PlayerPrefs.GetString("Username", "Guest")) { style = { color = Color.cyan, marginLeft = 5, unityFontStyleAndWeight = FontStyle.Bold } });
// _content.Add(userRow);
//
// _content.Add(CreateSubSection("LANGUAGE"));
// var langDropdown = new DropdownField(new List<string> { "English", "Tiếng Việt" }, LocalizationManager.Instance?.CurrentLanguage == "vi" ? 1 : 0);
// langDropdown.AddToClassList("custom-dropdown");
// langDropdown.RegisterValueChangedCallback(evt => {
// LocalizationManager.Instance?.LoadLanguage(evt.newValue == "Tiếng Việt" ? "vi" : "en");
// });
// _content.Add(langDropdown);
//
// _content.Add(CreateSubSection("UPDATES"));
// var versionBox = new VisualElement { style = { flexDirection = FlexDirection.Row, alignItems = Align.Center } };
// var versionLabel = new Label($"{GetT("VERSION")} {Application.version}"); versionLabel.AddToClassList("text-body");
// versionBox.Add(versionLabel);
// var checkBtn = new Button { text = GetT("CHECK_FOR_UPDATES") }; checkBtn.AddToClassList("button-spring");
// checkBtn.clicked += () => checkBtn.text = GetT("UP_TO_DATE");
// versionBox.Add(checkBtn);
// _content.Add(versionBox);
//
// _content.Add(CreateSubSection("CURSOR_MOUSE"));
// _content.Add(CreateSliderWithInput(GetT("CURSOR_SIZE"), 10, 150, PlayerPrefs.GetFloat("CursorSize", 40), val => uiManager.SetCursorSize(val)));
// var trailToggle = new Toggle(GetT("ENABLE_TRAIL")) { value = PlayerPrefs.GetInt("CursorTrail", 1) == 1 };
// trailToggle.RegisterValueChangedCallback(evt => uiManager.SetCursorTrail(evt.newValue));
// _content.Add(trailToggle);
// var rippleToggle = new Toggle(GetT("ENABLE_RIPPLES")) { value = PlayerPrefs.GetInt("CursorRipples", 1) == 1 };
// rippleToggle.RegisterValueChangedCallback(evt => uiManager.SetCursorRipples(evt.newValue));
// _content.Add(rippleToggle);
// _content.Add(CreateSliderWithInput(GetT("SENSITIVITY"), 0.1f, 5.0f, PlayerPrefs.GetFloat("MouseSensitivity", 1.0f), val => uiManager.SetMouseSensitivity(val)));
// _mouseMetricsLabel = new Label($"{GetT("MOUSE_LATENCY")} report: 0/sec latency: 0ms") { style = { fontSize = 11, color = Color.gray, marginTop = 5 } };
// _content.Add(_mouseMetricsLabel);
// }
//
// private void RenderVideoTab()
// {
// var header = CreateSection("VIDEO");
// _sectionHeaders["VIDEO"] = header;
// _content.Add(header);
//
// _content.Add(CreateSubSection("RENDERER"));
// var frameLimit = new DropdownField(GetT("FRAME_LIMITER"), new List<string> { "VSync", "Power Saving", "Optimal", "Unlimited" }, PlayerPrefs.GetInt("FrameLimiter", 2));
// frameLimit.RegisterValueChangedCallback(evt => ApplyFrameLimit(frameLimit.index));
// _content.Add(frameLimit);
// var fpsToggle = new Toggle(GetT("SHOW_FPS")) { value = _fpsVisible };
// fpsToggle.RegisterValueChangedCallback(evt => { _fpsVisible = evt.newValue; PlayerPrefs.SetInt("ShowFPS", _fpsVisible ? 1 : 0); PerformanceOverlay.SetVisible(_fpsVisible); });
// _content.Add(fpsToggle);
//
// _content.Add(CreateSubSection("LAYOUT"));
// Resolution native = Screen.currentResolution;
// var resList = Screen.resolutions.Select(r => $"{r.width}x{r.height}").Distinct().Select(s => s == $"{native.width}x{native.height}" ? s + " (native)" : s).ToList();
// string currentResStr = $"{Screen.width}x{Screen.height}";
// int currentResIdx = resList.FindIndex(s => s.StartsWith(currentResStr));
// if (currentResIdx == -1) currentResIdx = resList.FindIndex(s => s.Contains("native"));
// var resDropdown = new DropdownField(GetT("RESOLUTION"), resList, currentResIdx);
// resDropdown.RegisterValueChangedCallback(evt => {
// string[] parts = evt.newValue.Split(' ')[0].Split('x');
// int w = int.Parse(parts[0]), h = int.Parse(parts[1]);
// Screen.SetResolution(w, h, Screen.fullScreen);
// PlayerPrefs.SetInt("ScreenWidth", w); PlayerPrefs.SetInt("ScreenHeight", h);
// });
// _content.Add(resDropdown);
// var fullToggle = new Toggle(GetT("FULLSCREEN")) { value = Screen.fullScreen };
// fullToggle.RegisterValueChangedCallback(evt => { Screen.fullScreen = evt.newValue; PlayerPrefs.SetInt("Fullscreen", evt.newValue ? 1 : 0); });
// _content.Add(fullToggle);
// // _content.Add(CreateSliderWithInput(GetT("BACKGROUND_DIM"), 0, 100, PlayerPrefs.GetFloat("BackgroundDim", 50), val => ApplyBackgroundDim(val)));
// // _content.Add(CreateSliderWithInput(GetT("UI_SCALE"), 0.5f, 2.0f, PlayerPrefs.GetFloat("UIScale", 1.0f), val => uiManager.SetUIScale(val)));
// }
//
// private void RenderSoundTab()
// {
// // var header = CreateSection("SOUND");
// // _sectionHeaders["SOUND"] = header;
// // _content.Add(header);
//
// _audioSliders.Clear();
// // _content.Add(CreateSubSection("AUDIO_VOLUMES"));
// // _content.Add(CreateAudioSlider(GetT("MASTER"), "MasterVolume"));
// // _content.Add(CreateAudioSlider(GetT("MUSIC"), "MusicVolume"));
// // _content.Add(CreateAudioSlider(GetT("VFX"), "VFXVolume"));
// // _content.Add(CreateAudioSlider(GetT("PLAYER"), "PlayerVolume"));
// // _content.Add(CreateAudioSlider(GetT("UI"), "UIVolume"));
// _content.Add(new Label(GetT("SCROLL_HINT")) { style = { marginTop = 20, color = Color.gray, fontSize = 12 } });
// }
//
// private void RenderControlTab()
// {
// var header = CreateSection("CONTROL");
// _sectionHeaders["CONTROL"] = header;
// _content.Add(header);
//
// _content.Add(CreateSubSection("KEY_BINDINGS"));
// // if (uiManager.InputReader?.InputActions == null) return;
// // foreach (var map in uiManager.InputReader.InputActions.actionMaps)
// // {
// // var mapHeader = new Label(map.name.ToUpper()) { style = { fontSize = 14, unityFontStyleAndWeight = FontStyle.Bold, color = Color.cyan, marginTop = 15, marginBottom = 5 } };
// // _content.Add(mapHeader);
// // foreach (var action in map.actions)
// // {
// // if (action.name == "Look" || action.name == "Scroll" || action.name == "Navigate" || action.name == "Point" || action.name == "Click") continue;
// // if (action.bindings.Any(b => b.isComposite))
// // {
// // for (int i = 0; i < action.bindings.Count; i++)
// // if (action.bindings[i].isPartOfComposite && action.bindings[i].groups.Contains("Keyboard&Mouse"))
// // _content.Add(CreateRebindRow(action, i, $"{action.name} {action.bindings[i].name}".ToUpper()));
// // }
// // else
// // {
// // int idx = action.bindings.ToList().FindIndex(b => b.groups.Contains("Keyboard&Mouse"));
// // if (idx != -1) _content.Add(CreateRebindRow(action, idx, action.name.ToUpper()));
// // }
// // }
// // }
// // var resetBtn = new Button { text = GetT("RESET_ALL") }; resetBtn.AddToClassList("button-spring"); resetBtn.style.marginTop = 30; resetBtn.style.alignSelf = Align.Center;
// // resetBtn.clicked += () => { uiManager.InputReader.ResetBindings(); RefreshUI(); };
// // _content.Add(resetBtn);
// // }
//
// private void ApplyVideoSettings()
// {
// int frameLimitIdx = PlayerPrefs.GetInt("FrameLimiter", 2);
// ApplyFrameLimit(frameLimitIdx);
// _fpsVisible = PlayerPrefs.GetInt("ShowFPS", 0) == 1;
// PerformanceOverlay.SetVisible(_fpsVisible);
// float dim = PlayerPrefs.GetFloat("BackgroundDim", 50f);
// ApplyBackgroundDim(dim);
// }
//
// private void ApplyFrameLimit(int index)
// {
// switch (index)
// {
// case 0: QualitySettings.vSyncCount = 1; Application.targetFrameRate = -1; break;
// case 1: QualitySettings.vSyncCount = 0; Application.targetFrameRate = 60; break;
// case 2: QualitySettings.vSyncCount = 0; Application.targetFrameRate = 144; break;
// case 3: QualitySettings.vSyncCount = 0; Application.targetFrameRate = 999; break;
// }
// PlayerPrefs.SetInt("FrameLimiter", index);
// }
//
// private void ApplyBackgroundDim(float value)
// {
// PlayerPrefs.SetFloat("BackgroundDim", value);
// var dimOverlay = uiManager.Root.Q<VisualElement>("BackgroundDimOverlay");
// if (dimOverlay != null) dimOverlay.style.backgroundColor = new Color(0, 0, 0, value / 100f);
// }
//
// private void SetupHierarchicalVolumeOverlay()
// {
// _volumeContainer = new VisualElement { name = "GlobalVolumeOverlay" };
// _volumeContainer.style.position = Position.Absolute;
// _volumeContainer.style.right = 50; _volumeContainer.style.bottom = 50;
// _volumeContainer.style.width = 300; _volumeContainer.style.height = 300;
// _volumeContainer.style.display = DisplayStyle.None;
// _volumeContainer.pickingMode = PickingMode.Ignore;
// uiManager.Root.Add(_volumeContainer);
//
// _masterRing = CreateRing("Master", 120, cyan: true);
// _masterRing.style.right = 0; _masterRing.style.bottom = 0;
// _masterVolLabel = _masterRing.Q<Label>();
// _volumeContainer.Add(_masterRing);
//
// string[] subs = { "MusicVolume", "VFXVolume", "PlayerVolume", "UIVolume" };
// string[] shortNames = { "MUS", "VFX", "PLY", "UI" };
// for (int i = 0; i < subs.Length; i++)
// {
// var ring = CreateRing(shortNames[i], 70, false);
// float angle = (i * 30f) * Mathf.Deg2Rad;
// float radius = 140f;
// ring.style.right = 25 + Mathf.Sin(angle) * radius;
// ring.style.bottom = 25 + Mathf.Cos(angle) * radius;
// string key = subs[i];
// ring.RegisterCallback<PointerEnterEvent>(evt => _hoveredSubVolume = key);
// ring.RegisterCallback<PointerLeaveEvent>(evt => { if (_hoveredSubVolume == key) _hoveredSubVolume = null; });
// ring.pickingMode = PickingMode.Position;
// _subRings[key] = (ring, ring.Q<Label>());
// _volumeContainer.Add(ring);
// }
// }
//
// private VisualElement CreateRing(string text, float size, bool cyan)
// {
// var ring = new VisualElement();
// ring.style.width = size; ring.style.height = size;
// ring.style.backgroundColor = new Color(0, 0, 0, 0.85f);
// var radius = size / 2;
// ring.style.borderTopLeftRadius = radius; ring.style.borderTopRightRadius = radius;
// ring.style.borderBottomLeftRadius = radius; ring.style.borderBottomRightRadius = radius;
// ring.style.borderTopWidth = 3; ring.style.borderBottomWidth = 3;
// ring.style.borderLeftWidth = 3; ring.style.borderRightWidth = 3;
// ring.style.borderTopColor = ring.style.borderBottomColor = ring.style.borderLeftColor = ring.style.borderRightColor = cyan ? Color.cyan : new Color(0.7f, 0.7f, 0.7f);
// ring.style.justifyContent = Justify.Center; ring.style.alignItems = Align.Center;
// ring.style.position = Position.Absolute;
// var label = new Label("80%");
// label.style.color = Color.white; label.style.fontSize = size * 0.25f;
// label.style.unityFontStyleAndWeight = FontStyle.Bold;
// ring.Add(label);
// var title = new Label(text);
// title.style.color = Color.gray; title.style.fontSize = size * 0.15f;
// title.style.position = Position.Absolute; title.style.bottom = size * 0.15f;
// ring.Add(title);
// return ring;
// }
//
// private void OnMouseWheel(WheelEvent evt)
// {
// var mainMenuRoot = uiManager.Root.Q<VisualElement>("MainMenuRoot");
// bool isMainMenuVisible = mainMenuRoot != null && mainMenuRoot.style.display == DisplayStyle.Flex;
// if (!uiManager.IsSettingsOpen && isMainMenuVisible) return;
// VisualElement target = evt.target as VisualElement;
// bool isDirectUIInteraction = _hoveredSubVolume != null || (_hoveredSlider != null && _activeTab == "SOUND");
// if (!isDirectUIInteraction && target != null)
// {
// if (target is ScrollView || target.GetFirstAncestorOfType<ScrollView>() != null) return;
// }
// _overlayActiveCount++;
// ShowVolumeOverlay();
// if (_hoveredSubVolume != null) UpdateSubVolume(_hoveredSubVolume, -evt.delta.y * 2f);
// else if (_hoveredSlider != null && _activeTab == "SOUND")
// {
// float step = (_sliderMax - _sliderMin) / 100f;
// float newVal = Mathf.Clamp(_hoveredSlider.value - (evt.delta.y * step * 5f), _sliderMin, _sliderMax);
// _hoveredSlider.value = newVal;
// _hoveredOnChanged?.Invoke(newVal);
// }
// else UpdateMasterVolume(-evt.delta.y * 2f);
// evt.StopPropagation();
// }
//
// private void UpdateMasterVolume(float delta) => UpdateVolume("MasterVolume", _masterVol + delta);
//
// private void UpdateSubVolume(string key, float delta) => UpdateVolume(key, PlayerPrefs.GetFloat(key, 80f) + delta);
//
// private void UpdateVolume(string key, float volume, bool updateSlider = true)
// {
// volume = Mathf.Clamp(volume, 0f, 100f);
// PlayerPrefs.SetFloat(key, volume);
// // AudioManager.Instance?.SetVolume(key, volume);
//
// if (key == "MasterVolume")
// {
// _masterVol = volume;
// if (_masterVolLabel != null) _masterVolLabel.text = $"{Mathf.RoundToInt(volume)}%";
// }
// else
// {
// if (_subRings.TryGetValue(key, out var data)) data.label.text = $"{Mathf.RoundToInt(volume)}%";
// }
//
// if (updateSlider && _audioSliders.TryGetValue(key, out var sliderData))
// {
// sliderData.slider.SetValueWithoutNotify(volume);
// sliderData.input.value = volume.ToString("F1");
// }
// }
//
// private async void ShowVolumeOverlay()
// {
// _volumeContainer.BringToFront();
// uiManager.Root.Q<VisualElement>("CursorLayer")?.BringToFront();
// _volumeContainer.style.display = DisplayStyle.Flex;
// _volumeContainer.style.opacity = 1f;
// foreach (var kvp in _subRings) kvp.Value.label.text = $"{Mathf.RoundToInt(PlayerPrefs.GetFloat(kvp.Key, 80f))}%";
// _masterVolLabel.text = $"{Mathf.RoundToInt(_masterVol)}%";
// int currentId = _overlayActiveCount;
// await Task.Delay(3000);
// /*if (currentId == _overlayActiveCount && _hoveredSubVolume == null)
// {
// Tween.Custom(1f, 0f, duration: 0.5f, onValueChange: val => _volumeContainer.style.opacity = val)
// .OnComplete(() => { if (_volumeContainer.style.opacity == 0f) _volumeContainer.style.display = DisplayStyle.None; });
// }*/
// }
//
// private VisualElement CreateSection(string title)
// {
// var label = new Label(GetT(title));
// label.AddToClassList("text-heading");
// label.style.marginTop = 60;
// label.style.borderBottomWidth = 2;
// label.style.borderBottomColor = Color.cyan;
// label.style.paddingBottom = 10;
// return label;
// }
//
// private VisualElement CreateSubSection(string title)
// {
// var label = new Label(GetT(title));
// label.AddToClassList("setting-section-header");
// label.style.marginTop = 20;
// return label;
// }
//
// private VisualElement CreateSliderWithInput(string labelText, float min, float max, float startVal, Action<float> OnValueChanged, string audioKey = null)
// {
// var row = new VisualElement { style = { flexDirection = FlexDirection.Row, alignItems = Align.Center, marginTop = 5, marginBottom = 5 } };
// var label = new Label(labelText) { style = { width = Length.Percent(35) } }; label.AddToClassList("text-body");
// var slider = new Slider(min, max) { value = startVal, style = { flexGrow = 1 } };
// var input = new TextField { value = startVal.ToString("F1"), style = { width = 50, marginLeft = 10 } }; input.AddToClassList("input-field");
//
// if (audioKey != null) _audioSliders[audioKey] = (slider, input);
//
// slider.RegisterCallback<PointerEnterEvent>(evt => { _hoveredSlider = slider; _hoveredOnChanged = OnValueChanged; _sliderMin = min; _sliderMax = max; });
// slider.RegisterCallback<PointerLeaveEvent>(evt => { if (_hoveredSlider == slider) { _hoveredSlider = null; _hoveredOnChanged = null; } });
// slider.RegisterValueChangedCallback(evt => { float val = Mathf.Round(evt.newValue * 10f) / 10f; if (input.panel?.focusController?.focusedElement != input.ElementAt(0)) input.value = val.ToString("F1"); OnValueChanged?.Invoke(val); });
// input.RegisterValueChangedCallback(evt => { if (float.TryParse(evt.newValue, out float val)) { slider.value = Mathf.Clamp(val, min, max); OnValueChanged?.Invoke(slider.value); } });
// row.Add(label); row.Add(slider); row.Add(input); return row;
// }
//
// private VisualElement CreateAudioSlider(string label, string prefKey)
// {
// var sliderRow = CreateSliderWithInput(label, 0, 100, PlayerPrefs.GetFloat(prefKey, 80), val => {
// UpdateVolume(prefKey, val, false);
// }, prefKey);
// sliderRow.RegisterCallback<WheelEvent>(evt => {
// UpdateVolume(prefKey, PlayerPrefs.GetFloat(prefKey, 80f) - (evt.delta.y * 2f));
// });
// return sliderRow;
// }
//
// private VisualElement CreateRebindRow(UnityEngine.InputSystem.InputAction action, int bindingIndex, string labelText)
// {
// var row = new VisualElement(); row.AddToClassList("rebind-row"); row.style.flexDirection = FlexDirection.Row; row.style.justifyContent = Justify.SpaceBetween; row.style.alignItems = Align.Center; row.style.paddingTop = row.style.paddingBottom = 10; row.style.borderBottomWidth = 1; row.style.borderBottomColor = new Color(1, 1, 1, 0.1f);
// var label = new Label(labelText); label.AddToClassList("rebind-label"); label.style.color = Color.white; row.Add(label);
// var btn = new Button { text = action.GetBindingDisplayString(bindingIndex).ToUpper() }; btn.AddToClassList("rebind-button"); btn.style.width = 150;
// btn.clicked += () => StartRebinding(action, bindingIndex, btn); row.Add(btn);
// return row;
// }
//
// private void StartRebinding(UnityEngine.InputSystem.InputAction action, int bindingIndex, Button btn)
// {
// btn.text = "> <"; btn.style.color = Color.yellow; action.actionMap.Disable();
// var op = action.PerformInteractiveRebinding(bindingIndex).WithControlsExcluding("<Mouse>/position").WithControlsExcluding("<Mouse>/delta").WithControlsExcluding("<Keyboard>/escape").OnMatchWaitForAnother(0.1f)
// .OnComplete(operation => { btn.text = action.GetBindingDisplayString(bindingIndex).ToUpper(); btn.style.color = Color.white; operation.Dispose(); action.actionMap.Enable(); uiManager.InputReader.SaveBindings(); })
// .OnCancel(operation => { btn.text = action.GetBindingDisplayString(bindingIndex).ToUpper(); btn.style.color = Color.white; operation.Dispose(); action.actionMap.Enable(); });
// op.Start();
// }
//
// private void OnKeyDown(KeyDownEvent evt)
// {
// if (_hoveredSlider == null) return;
// float step = (_sliderMax - _sliderMin) / 100f;
// if (evt.keyCode == KeyCode.LeftArrow) _hoveredSlider.value -= step;
// if (evt.keyCode == KeyCode.RightArrow) _hoveredSlider.value += step;
// }
//
// public override void Update()
// {
// if (_mouseMetricsLabel != null && _mouseMetricsLabel.panel != null)
// {
// var (polling, latency) = MouseMetricsHelper.GetMetrics();
// _mouseMetricsLabel.text = $"{GetT("MOUSE_LATENCY")} report: {polling}/sec latency: {latency:F0}ms";
// }
// }
//
// /*public override async Task PlayTransitionIn()
// {
// root.style.display = DisplayStyle.Flex;
// _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)));
// }
//
// public override async Task PlayTransitionOut()
// {
// await Tween.Custom(0f, -100f, duration: 0.3f, ease: Ease.InQuad, onValueChange: val => _sidebar.style.translate = new StyleTranslate(new Translate(Length.Percent(val), 0)));
// Hide();
// }*/
//
// private void OnDestroy()
// {
// if (LocalizationManager.Instance != null)
// {
// LocalizationManager.Instance.OnLanguageChanged -= OnLanguageChanged;
// }
// }
// }
// }

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 5534bcf4869df944883c6fd2a17a6a5a

View File

@@ -1,110 +0,0 @@
using UnityEngine;
using UnityEngine.UIElements;
using System.Collections.Generic;
namespace Baba_yaga.UI
{
public static class UIAudioHelper
{
public static void BindFeedback(VisualElement root)
{
if (root == null) return;
// Bind Buttons (Click & Hover)
var buttons = root.Query<Button>().ToList();
foreach (var btn in buttons)
{
btn.RegisterCallback<PointerEnterEvent>(OnButtonHover);
btn.RegisterCallback<ClickEvent>(OnButtonClick);
}
// Bind Toggles
var toggles = root.Query<Toggle>().ToList();
foreach (var tgl in toggles)
{
tgl.RegisterValueChangedCallback(OnToggleChanged);
}
// Bind TextFields (Focus & Typing)
var textFields = root.Query<TextField>().ToList();
foreach (var tf in textFields)
{
tf.RegisterCallback<FocusEvent>(OnTextFieldFocus);
tf.RegisterCallback<KeyDownEvent>(OnTextFieldKeyDown, TrickleDown.TrickleDown);
}
}
private static void OnButtonHover(PointerEnterEvent evt)
{
var target = evt.target as VisualElement;
string sound = "menuclick"; // Default hover
string name = target.name.ToLower();
if (name.Contains("back")) sound = "menu-back-hover";
else if (name.Contains("play")) sound = "menu-play-hover";
else if (name.Contains("option") || name.Contains("setting")) sound = "menu-options-hover";
else if (name.Contains("exit") || name.Contains("quit")) sound = "menu-exit-hover";
// AudioManager.PlayGlobal(sound, 0.5f, 1.05f);
}
private static void OnButtonClick(ClickEvent evt)
{
var target = evt.target as VisualElement;
string sound = "menuclick"; // Default click
string name = target.name.ToLower();
if (name.Contains("back")) sound = "menu-back-click";
else if (name.Contains("close")) sound = "click-close";
else if (name.Contains("confirm") || name.Contains("start") || name.Contains("create")) sound = "click-short-confirm";
else if (name.Contains("play")) sound = "menu-play-click";
else if (name.Contains("option") || name.Contains("setting")) sound = "menu-options-click";
else if (name.Contains("exit") || name.Contains("quit")) sound = "menu-exit-click";
else if (name.Contains("retry") || name.Contains("restart")) sound = "pause-retry-click";
float randomPitch = Random.Range(0.98f, 1.02f);
// AudioManager.PlayGlobal(sound, 1f, randomPitch);
}
private static void OnToggleChanged(ChangeEvent<bool> evt)
{
string sound = evt.newValue ? "check-on" : "check-off";
// AudioManager.PlayGlobal(sound, 0.8f);
}
private static void OnTextFieldFocus(FocusEvent evt)
{
// AudioManager.PlayGlobal("UI_Focus", 0.6f);
}
private static void OnTextFieldKeyDown(KeyDownEvent evt)
{
// Osu style typing feedback
switch (evt.keyCode)
{
case KeyCode.Return:
case KeyCode.KeypadEnter:
// AudioManager.PlayGlobal("key-confirm", 0.8f);
break;
case KeyCode.Backspace:
case KeyCode.Delete:
// AudioManager.PlayGlobal("key-delete", 0.7f);
break;
case KeyCode.Space:
case KeyCode.CapsLock:
// AudioManager.PlayGlobal("key-caps", 0.7f);
break;
case KeyCode.UpArrow:
case KeyCode.DownArrow:
case KeyCode.LeftArrow:
case KeyCode.RightArrow:
// AudioManager.PlayGlobal("key-movement", 0.6f);
break;
default:
// Play random variation for normal keys (key-press-1 to 4)
// AudioManager.PlayRandomGlobal("key-press", 4, 0.5f, Random.Range(0.95f, 1.1f));
break;
}
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 28373d86c046d8248b3788daaa019217

View File

@@ -1,438 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UIElements;
using PrimeTween;
using Tween = PrimeTween.Tween;
using Ease = PrimeTween.Ease;
using Baba_yaga;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Baba_yaga.UI
{
[RequireComponent(typeof(UIDocument))]
[UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "Hallucinate.UI", sourceAssembly: "Opsive.UltimateCharacterController")]
public class UIManager : MonoBehaviour
{
public static UIManager Instance { get; private set; }
private UIDocument _uiDocument;
private VisualElement _rootElement;
public VisualElement Root => _rootElement;
private VisualElement _cursorLayer;
private VisualElement _mainCursor;
private readonly Dictionary<Type, BaseUIController> _controllers = new Dictionary<Type, BaseUIController>();
private readonly Stack<BaseUIController> _history = new Stack<BaseUIController>();
[Header("References")]
// [SerializeField] private InputReader inputReader;
// public InputReader InputReader => inputReader;
[Header("Game Metadata")]
[SerializeField] private Texture2D gameIcon;
[Header("Cursor & Effects Settings")]
[SerializeField] private Sprite cursorSprite;
[SerializeField] private Sprite cursorTrailSprite;
[SerializeField, Range(10f, 150f)] private float cursorSize = 40f;
[SerializeField, Range(2, 50)] private float trailDistanceThreshold = 10f;
[SerializeField] private bool enableRipples = true;
[SerializeField] private Color rippleColor = new Color(0, 1, 0.8f, 0.4f);
[Header("UI Templates & Global Styles")]
[SerializeField] private VisualTreeAsset loginTemplate;
[SerializeField] private VisualTreeAsset mainMenuTemplate;
[SerializeField] private VisualTreeAsset lobbyTemplate;
[SerializeField] private VisualTreeAsset roomItemTemplate;
[SerializeField] private VisualTreeAsset profileTemplate;
[SerializeField] private VisualTreeAsset settingsTemplate;
[SerializeField] private VisualTreeAsset hudTemplate;
[SerializeField] private VisualTreeAsset pauseMenuTemplate;
[SerializeField] private StyleSheet globalStyleSheet;
private LoginController _loginController;
private MainMenuController _mainMenuController;
private LobbyController _lobbyController;
// private SettingsController _settingsController;
private PauseMenuController _pauseMenuController;
// Osu Trail Pooling
private const int MAX_TRAIL_PARTICLES = 60;
private readonly List<VisualElement> _trailPool = new List<VisualElement>();
private int _currentTrailIndex = 0;
private Vector2 _lastTrailSpawnPos;
private bool _isSettingsOpen = false;
public bool IsSettingsOpen => _isSettingsOpen;
private bool _isPauseMenuOpen = false;
public bool IsPauseMenuOpen => _isPauseMenuOpen;
private const string UI_SCALE_KEY = "UIScale";
#if UNITY_EDITOR
private void OnValidate()
{
if (gameIcon == null)
{
var icons = PlayerSettings.GetIcons(UnityEditor.Build.NamedBuildTarget.Unknown, IconKind.Any);
if (icons != null && icons.Length > 0)
{
gameIcon = icons[0];
UnityEditor.EditorUtility.SetDirty(this);
}
}
}
#endif
private void Awake()
{
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
Instance = this;
DontDestroyOnLoad(gameObject);
_uiDocument = GetComponent<UIDocument>();
UnityEngine.Cursor.visible = false;
LoadGeneralSettings();
ApplySavedUIScale();
}
private void LoadGeneralSettings()
{
cursorSize = PlayerPrefs.GetFloat("CursorSize", 40f);
enableRipples = PlayerPrefs.GetInt("CursorRipples", 1) == 1;
}
public void SetCursorSize(float size)
{
cursorSize = size;
PlayerPrefs.SetFloat("CursorSize", size);
if (_mainCursor != null)
{
_mainCursor.style.width = cursorSize;
_mainCursor.style.height = cursorSize;
}
foreach(var p in _trailPool) { p.style.width = cursorSize; p.style.height = cursorSize; }
}
public void SetCursorTrail(bool enabled)
{
PlayerPrefs.SetInt("CursorTrail", enabled ? 1 : 0);
}
public void SetCursorRipples(bool enabled)
{
enableRipples = enabled;
PlayerPrefs.SetInt("CursorRipples", enabled ? 1 : 0);
}
public void SetMouseSensitivity(float sensitivity)
{
PlayerPrefs.SetFloat("MouseSensitivity", sensitivity);
if (Baba_yaga.SettingsManager.Instance != null)
{
Baba_yaga.SettingsManager.Instance.SetSensitivity(sensitivity);
}
}
/*public void OnGameStarted()
{
_ = Push<HUDController>();
}
public void OnBackToMenu()
{
_ = Push<MainMenuController>();
}*/
public void SetUIScale(float scale)
{
if (_uiDocument == null || _uiDocument.panelSettings == null) return;
_uiDocument.panelSettings.scale = scale * 1.3f;
PlayerPrefs.SetFloat(UI_SCALE_KEY, scale);
PlayerPrefs.Save();
}
private void ApplySavedUIScale()
{
float savedScale = PlayerPrefs.GetFloat(UI_SCALE_KEY, 1.0f);
SetUIScale(savedScale);
}
private void Start()
{
if (_uiDocument == null) _uiDocument = GetComponent<UIDocument>();
_rootElement = _uiDocument.rootVisualElement;
if (globalStyleSheet != null)
_rootElement.panel.visualTree.styleSheets.Add(globalStyleSheet);
var dimOverlay = new VisualElement { name = "BackgroundDimOverlay" };
dimOverlay.style.position = Position.Absolute;
dimOverlay.style.width = Length.Percent(100);
dimOverlay.style.height = Length.Percent(100);
dimOverlay.pickingMode = PickingMode.Ignore;
float savedDim = PlayerPrefs.GetFloat("BackgroundDim", 50f);
dimOverlay.style.backgroundColor = new Color(0, 0, 0, savedDim / 100f);
_rootElement.Add(dimOverlay);
_cursorLayer = new VisualElement { name = "CursorLayer" };
_cursorLayer.style.position = Position.Absolute;
_cursorLayer.style.width = Length.Percent(100);
_cursorLayer.style.height = Length.Percent(100);
_cursorLayer.pickingMode = PickingMode.Ignore;
_rootElement.Add(_cursorLayer);
InitializeTrailPool();
_mainCursor = new VisualElement { name = "MainCursor" };
_mainCursor.style.position = Position.Absolute;
_mainCursor.style.width = cursorSize;
_mainCursor.style.height = cursorSize;
_mainCursor.style.backgroundImage = new StyleBackground(Background.FromSprite(cursorSprite));
// Căn giữa sprite hình tròn bằng translate
_mainCursor.style.translate = new StyleTranslate(new Translate(Length.Percent(-50), Length.Percent(-50)));
_mainCursor.pickingMode = PickingMode.Ignore;
_cursorLayer.Add(_mainCursor);
_rootElement.RegisterCallback<PointerDownEvent>(OnGlobalClick, TrickleDown.TrickleDown);
/*if (inputReader != null)
{
inputReader.OnToggleSettingsEvent += ToggleSettings;
inputReader.OnCancelEvent += HandleCancel;
}
*/
InitializeControllers();
/*CheckLoginStatus();*/
}
private void InitializeTrailPool()
{
for (int i = 0; i < MAX_TRAIL_PARTICLES; i++)
{
var particle = new VisualElement();
particle.style.position = Position.Absolute;
particle.style.width = cursorSize;
particle.style.height = cursorSize;
particle.style.backgroundImage = new StyleBackground(Background.FromSprite(cursorTrailSprite));
particle.style.translate = new StyleTranslate(new Translate(Length.Percent(-50), Length.Percent(-50)));
particle.style.opacity = 0;
particle.style.display = DisplayStyle.None;
particle.pickingMode = PickingMode.Ignore;
_cursorLayer.Add(particle);
_trailPool.Add(particle);
}
}
/*private void CheckLoginStatus()
{
string savedName = PlayerPrefs.GetString("Username", "");
if (string.IsNullOrEmpty(savedName)) _ = Push<LoginController>();
else _ = Push<MainMenuController>();
}
public void OnLoginSuccess() => _ = Push<MainMenuController>();
private void OnDestroy()
{
if (inputReader != null)
{
inputReader.OnToggleSettingsEvent -= ToggleSettings;
inputReader.OnCancelEvent -= HandleCancel;
}
}*/
/*private void HandleCancel()
{
if (_isSettingsOpen) ToggleSettings();
else if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "Main Scene")
{
TogglePauseMenu();
}
}*/
/*public async void TogglePauseMenu()
{
if (_pauseMenuController == null) return;
if (!_isPauseMenuOpen)
{
_isPauseMenuOpen = true;
_pauseMenuController.Root.BringToFront();
if (_cursorLayer != null) _cursorLayer.BringToFront();
// Unlock cursor when menu is open
UnityEngine.Cursor.lockState = CursorLockMode.None;
UnityEngine.Cursor.visible = false;
await _pauseMenuController.PlayTransitionIn();
}
else
{
_isPauseMenuOpen = false;
// Re-lock cursor when menu is closed
if (!_isSettingsOpen)
{
UnityEngine.Cursor.lockState = CursorLockMode.Locked;
}
await _pauseMenuController.PlayTransitionOut();
}
}*/
/*public async void ToggleSettings()
{
if (_settingsController == null) return;
if (!_isSettingsOpen)
{
_isSettingsOpen = true;
_settingsController.Root.BringToFront();
if (_cursorLayer != null) _cursorLayer.BringToFront();
await /*_settingsController.PlayTransitionIn();#1#
}
else
{
_isSettingsOpen = false;
await /*_settingsController.PlayTransitionOut();#1#
}
}
*/
private void Update()
{
if (_history.Count > 0) _history.Peek().Update();
UpdateCursorInput();
}
private void UpdateCursorInput()
{
if (!Application.isFocused || _cursorLayer == null) return;
// Dùng cách tính tọa độ thủ công để tránh offset khi pivot ở giữa
Vector2 mousePos = Input.mousePosition;
float scale = GetCurrentScale();
Vector2 uiPos = new Vector2(mousePos.x / scale, (Screen.height - mousePos.y) / scale);
if (_mainCursor != null)
{
_mainCursor.style.left = uiPos.x;
_mainCursor.style.top = uiPos.y;
}
bool trailEnabled = PlayerPrefs.GetInt("CursorTrail", 1) == 1;
if (trailEnabled && cursorTrailSprite != null)
{
float dist = Vector2.Distance(uiPos, _lastTrailSpawnPos);
if (dist > trailDistanceThreshold)
{
SpawnPooledTrail(uiPos);
_lastTrailSpawnPos = uiPos;
}
}
}
private void SpawnPooledTrail(Vector2 pos)
{
var particle = _trailPool[_currentTrailIndex];
_currentTrailIndex = (_currentTrailIndex + 1) % MAX_TRAIL_PARTICLES;
/*Tween.StopAll(particle);*/
particle.style.display = DisplayStyle.Flex;
particle.style.left = pos.x;
particle.style.top = pos.y;
particle.style.opacity = 0f;
particle.style.scale = Vector3.one;
}
private float GetCurrentScale() => (_uiDocument != null && _uiDocument.panelSettings != null) ? _uiDocument.panelSettings.scale : 1.0f;
private void OnGlobalClick(PointerDownEvent evt)
{
if (!enableRipples || _cursorLayer == null) return;
var ripple = new VisualElement();
ripple.style.position = Position.Absolute;
ripple.style.width = cursorSize;
ripple.style.height = cursorSize;
ripple.style.translate = new StyleTranslate(new Translate(Length.Percent(-50), Length.Percent(-50)));
ripple.style.left = evt.localPosition.x;
ripple.style.top = evt.localPosition.y;
var radius = new StyleLength(new Length(50, LengthUnit.Percent));
ripple.style.borderTopLeftRadius = radius; ripple.style.borderTopRightRadius = radius;
ripple.style.borderBottomLeftRadius = radius; ripple.style.borderBottomRightRadius = radius;
ripple.style.borderTopColor = rippleColor; ripple.style.borderBottomColor = rippleColor;
ripple.style.borderLeftColor = rippleColor; ripple.style.borderRightColor = rippleColor;
ripple.style.borderTopWidth = 2; ripple.style.borderBottomWidth = 2;
ripple.pickingMode = PickingMode.Ignore;
_cursorLayer.Add(ripple);
/*Tween.Custom(Vector3.one, Vector3.one * 2.5f, duration: 0.4f, onValueChange: val => ripple.style.scale = new StyleScale(new Scale(val)), ease: Ease.OutQuad);
Tween.Custom(1f, 0f, duration: 0.4f, onValueChange: val => ripple.style.opacity = val).OnComplete(() => ripple.RemoveFromHierarchy());*/
}
private void InitializeControllers()
{
try
{
_mainMenuController = RegisterController<MainMenuController>(mainMenuTemplate);
if (_mainMenuController != null && gameIcon != null) _mainMenuController.SetGameIcon(gameIcon);
_lobbyController = RegisterController<LobbyController>(lobbyTemplate);
if (_lobbyController != null) _lobbyController.SetRoomTemplate(roomItemTemplate);
RegisterController<ProfileController>(profileTemplate);
// _settingsController = RegisterController<SettingsController>(settingsTemplate);
RegisterController<HUDController>(hudTemplate);
_pauseMenuController = RegisterController<PauseMenuController>(pauseMenuTemplate);
_loginController = RegisterController<LoginController>(loginTemplate);
}
catch (Exception e) { Debug.LogError($"[UIManager] Failed to initialize controllers: {e}"); }
}
private T RegisterController<T>(VisualTreeAsset template) where T : BaseUIController
{
if (template == null || _rootElement == null) return null;
VisualElement instance = template.Instantiate();
if (instance == null) return null;
instance.style.flexGrow = 1; instance.style.position = Position.Absolute;
instance.style.width = Length.Percent(100); instance.style.height = Length.Percent(100);
instance.style.display = DisplayStyle.None;
_rootElement.Add(instance);
if (_cursorLayer != null) _cursorLayer.BringToFront();
var controller = ScriptableObject.CreateInstance<T>();
controller.Initialize(instance, this);
_controllers[typeof(T)] = controller;
return controller;
}
/*public async Task Push<T>() where T : BaseUIController
{
if (!_controllers.TryGetValue(typeof(T), out var newScreen)) return;
if (_history.Count > 0 && _history.Peek() == newScreen) return;
if (_history.Count > 0) await _history.Peek().PlayTransitionOut();
_history.Push(newScreen);
await newScreen.PlayTransitionIn();
if (_cursorLayer != null) _cursorLayer.BringToFront();
}
public async Task Pop()
{
if (_history.Count <= 1) return;
await _history.Pop().PlayTransitionOut();
if (_history.Count > 0) await _history.Peek().PlayTransitionIn();
if (_cursorLayer != null) _cursorLayer.BringToFront();
}*/
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: bcb7b8ed439bb4546b0648c627c2ce5d

View File

@@ -1,71 +0,0 @@
using UnityEngine;
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SlashMeshGenerator : MonoBehaviour
{
[Header("Mesh Settings")]
public int segments = 10; // Số lượng phân đoạn (càng cao càng mượt)
public float length = 5f; // Chiều dài vệt chém
public float width = 0.5f; // Chiều rộng ở giữa
public float curviness = 1f; // Độ cong của nhát chém
[ContextMenu("Generate Slash Mesh")]
public void GenerateMesh()
{
Mesh mesh = new Mesh();
mesh.name = "SukunaSlashMesh";
int vertexCount = (segments + 1) * 2;
Vector3[] vertices = new Vector3[vertexCount];
Vector2[] uvs = new Vector2[vertexCount];
int[] triangles = new int[segments * 6];
for (int i = 0; i <= segments; i++)
{
float t = (float)i / segments; // Tiến trình từ 0 đến 1
// Tính toán vị trí X (chiều dài)
float x = (t - 0.5f) * length;
// Tính toán độ nhọn (Width Taper): Nhỏ ở 2 đầu, to ở giữa
// Dùng hàm Sin để tạo độ mượt hoặc (1 - |2t-1|)
float currentWidth = Mathf.Sin(t * Mathf.PI) * width;
// Tính toán độ cong (Y Offset)
float yOffset = Mathf.Pow((t - 0.5f) * 2f, 2f) * curviness;
// Tạo 2 đỉnh (trên và dưới) cho mỗi phân đoạn
vertices[i * 2] = new Vector3(x, yOffset + currentWidth / 2f, 0);
vertices[i * 2 + 1] = new Vector3(x, yOffset - currentWidth / 2f, 0);
// Gán UV (để Shader chạy đúng)
uvs[i * 2] = new Vector2(t, 1);
uvs[i * 2 + 1] = new Vector2(t, 0);
// Tạo tam giác (trừ phân đoạn cuối)
if (i < segments)
{
int start = i * 2;
triangles[i * 6] = start;
triangles[i * 6 + 1] = start + 2;
triangles[i * 6 + 2] = start + 1;
triangles[i * 6 + 3] = start + 1;
triangles[i * 6 + 4] = start + 2;
triangles[i * 6 + 5] = start + 3;
}
}
mesh.vertices = vertices;
mesh.uv = uvs;
mesh.triangles = triangles;
mesh.RecalculateNormals();
mesh.RecalculateBounds();
GetComponent<MeshFilter>().mesh = mesh;
}
void Awake()
{
GenerateMesh();
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 78fcc45270373164cadbaa6681bab73b

View File

@@ -1,69 +0,0 @@
using UnityEngine;
using Baba_yaga;
public class SukunaAbilityController : MonoBehaviour
{
[Header("Dependencies")]
// [SerializeField] private InputReader inputReader;
[Header("VFX Projectiles")]
public GameObject blackProjectilePrefab;
public GameObject redProjectilePrefab;
[Header("Settings")]
public float attackRate = 0.15f;
public float forwardOffset = 1.5f;
public float verticalOffset = 1.0f;
[Header("Random Rotation Ranges")]
public Vector2 rangeX = new Vector2(-360f, 360f);
public Vector2 rangeY = new Vector2(-10f, 10f);
public Vector2 rangeZ = new Vector2(50f, 120f);
private float lastAttackTime = 0f;
private void Update()
{
// if (inputReader != null && inputReader.IsAttackHeld)
// {
// if (Time.time - lastAttackTime >= attackRate)
// {
// PerformDismantle();
// lastAttackTime = Time.time;
// }
// }
}
private void PerformDismantle()
{
GameObject selectedPrefab = GetRandomSlashVariant();
if (selectedPrefab == null) return;
// Vị trí spawn trước mặt Player
Vector3 spawnPos = transform.position + transform.forward * forwardOffset + Vector3.up * verticalOffset;
// Tạo góc xoay ngẫu nhiên theo yêu cầu của bạn
float randX = Random.Range(rangeX.x, rangeX.y);
float randY = Random.Range(rangeY.x, rangeY.y);
float randZ = Random.Range(rangeZ.x, rangeZ.y);
// Kết hợp với hướng của Player
Quaternion spawnRot = transform.rotation * Quaternion.Euler(randX, randY, randZ);
// Tạo đạn
GameObject projectile = Instantiate(selectedPrefab, spawnPos, spawnRot);
// Bắt đạn bay về phía trước (hướng nhìn của Player)
if (projectile.TryGetComponent<SukunaProjectile>(out var projScript))
{
projScript.SetDirection(transform.forward);
}
}
private GameObject GetRandomSlashVariant()
{
float chance = Random.Range(0f, 100f);
if (chance <= 20f) return redProjectilePrefab != null ? redProjectilePrefab : blackProjectilePrefab;
return blackProjectilePrefab;
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 1630760c9d97a5f4eb1bc179549c95cd

View File

@@ -1,230 +0,0 @@
// using UnityEngine;
// using UnityEngine.Rendering;
// using UnityEngine.Rendering.Universal;
// using System.Collections;
// using System.Collections.Generic;
//
// namespace Baba_yaga
// {
// [UnityEngine.Scripting.APIUpdating.MovedFrom(true, sourceNamespace: "OnlyScove.Scripts", sourceAssembly: "Opsive.UltimateCharacterController")]
public class SukunaDomainController : MonoBehaviour
// {
// [Header("References")]
// // public PlayerStateMachine playerStateMachine;
// public GameObject slashPrefab;
// public GameObject shrinePrefab;
// public VolumeProfile domainVolumeProfile;
// public Transform cinematicCameraPoint;
//
// [Header("Domain Settings")]
// public float domainRadius = 15f;
// public float domainDuration = 10f;
//
// [Tooltip("Số lượng vệt chém tạo ra mỗi giây")]
// public float slashRate = 15f;
//
// public float shrineRiseHeight = 7f; // Độ sâu bắt đầu của miếu
//
// [Tooltip("Khoảng cách từ Pivot của Miếu đến mặt sàn nơi Player đứng")]
// public float shrineFloorOffset = 0.5f;
//
// public float camMoveSpeed = 4f;
//
// private bool isActive = false;
// private List<GameObject> activeSlashes = new List<GameObject>();
// private Volume localVolume;
// private GameObject spawnedShrine;
//
// // private void Start()
// // {
// // if (playerStateMachine == null)
// // playerStateMachine = GetComponent<PlayerStateMachine>();
// //
// // if (playerStateMachine != null && playerStateMachine.Input != null)
// // {
// // playerStateMachine.Input.OnPreviousInteractEvent += HandleDomainExpansion;
// // Debug.Log("<color=green>[Sukuna] Sẵn sàng. slashRate: " + slashRate + "</color>");
// // }
// // }
//
// // private void OnDestroy()
// // {
// // if (playerStateMachine != null && playerStateMachine.Input != null)
// // {
// // playerStateMachine.Input.OnPreviousInteractEvent -= HandleDomainExpansion;
// // }
// // }
//
// private void HandleDomainExpansion()
// {
// if (isActive) return;
// Debug.Log("<color=red>[Sukuna] RYŌIKI TENKAI: FUKUMA MIZUZUSHI!</color>");
// StartCoroutine(DomainSequence());
// }
//
// // private IEnumerator DomainSequence()
// // {
// // isActive = true;
// //
// // // Lưu vị trí ban đầu của Player (Vị trí thực tế trên mặt đất)
// // Vector3 playerStartPos = playerStateMachine.transform.position;
// // playerStateMachine.SetControl(false);
// //
// // CameraController camController = playerStateMachine.Cam;
// // bool originalCamEnabled = true;
// // Transform mainCam = Camera.main.transform;
// //
// // if (camController != null)
// // {
// // originalCamEnabled = camController.enabled;
// // camController.enabled = false;
// // }
// //
// // // 1. Tạo Volume (Bóng bong lãnh địa)
// // GameObject volumeObj = new GameObject("SukunaDomainVolume");
// // volumeObj.transform.position = playerStartPos;
// // localVolume = volumeObj.AddComponent<Volume>();
// // localVolume.isGlobal = false;
// // localVolume.priority = 100;
// // localVolume.profile = domainVolumeProfile;
// // SphereCollider volumeCollider = volumeObj.AddComponent<SphereCollider>();
// // volumeCollider.isTrigger = true;
// // volumeCollider.radius = 0.1f;
// //
// // // 2. Mọc miếu và đẩy Player
// // if (shrinePrefab != null)
// // {
// // // Spawn miếu ở vị trí rất sâu dưới chân Player
// // Vector3 shrineSpawnPos = playerStartPos - Vector3.up * shrineRiseHeight;
// // spawnedShrine = Instantiate(shrinePrefab, shrineSpawnPos, playerStateMachine.transform.rotation);
// //
// // float riseDuration = 2.0f;
// // float elapsed = 0;
// // while (elapsed < riseDuration)
// // {
// // elapsed += Time.deltaTime;
// // float t = Mathf.SmoothStep(0, 1, elapsed / riseDuration);
// //
// // // Di chuyển miếu lên dần dần
// // Vector3 currentShrinePos = Vector3.Lerp(shrineSpawnPos, playerStartPos, t);
// // spawnedShrine.transform.position = currentShrinePos;
// //
// // // Logic đẩy Player:
// // // floorY là độ cao mặt sàn của miếu tại khung hình hiện tại
// // float floorY = currentShrinePos.y + shrineFloorOffset;
// //
// // // Nếu mặt sàn của miếu đã trồi lên cao hơn vị trí chân Player ban đầu
// // if (floorY > playerStartPos.y)
// // {
// // // Player đi theo miếu
// // playerStateMachine.transform.position = new Vector3(playerStartPos.x, floorY, playerStartPos.z);
// // }
// // else
// // {
// // // Player đứng yên trên mặt đất ban đầu, chờ miếu trồi lên đỡ
// // playerStateMachine.transform.position = playerStartPos;
// // }
// //
// // // Mở rộng bán kính Volume
// // volumeCollider.radius = Mathf.Lerp(0.1f, domainRadius, t);
// //
// // // Lia Camera mượt mà
// // if (cinematicCameraPoint != null)
// // {
// // mainCam.position = Vector3.Lerp(mainCam.position, cinematicCameraPoint.position, Time.deltaTime * camMoveSpeed);
// // mainCam.rotation = Quaternion.Slerp(mainCam.rotation, Quaternion.LookRotation((playerStateMachine.transform.position + Vector3.up * 2f) - mainCam.position), Time.deltaTime * camMoveSpeed);
// // }
// // yield return null;
// // }
// // }
//
// // 3. Thực thi chém liên tục dựa trên slashRate
// float timer = 0;
// float slashCooldown = 1f / slashRate;
// float lastSlashTime = 0;
//
// while (timer < domainDuration)
// {
// timer += Time.deltaTime;
//
// if (timer - lastSlashTime >= slashCooldown)
// {
// SpawnRandomSlash(playerStateMachine.transform.position);
// lastSlashTime = timer;
// }
//
// // Camera luôn theo dõi Player trên đỉnh miếu
// if (cinematicCameraPoint != null)
// {
// mainCam.position = Vector3.Lerp(mainCam.position, cinematicCameraPoint.position, Time.deltaTime * camMoveSpeed * 0.5f);
// mainCam.LookAt(playerStateMachine.transform.position + Vector3.up * 2f);
// }
// yield return null;
// }
//
// // 4. Miếu sụp xuống (Player đứng lại vị trí Y ban đầu)
// if (spawnedShrine != null)
// {
// float sinkTime = 1f;
// float elapsed = 0;
// Vector3 currentShrinePos = spawnedShrine.transform.position;
// Vector3 targetSinkPos = currentShrinePos - Vector3.up * shrineRiseHeight;
// while (elapsed < sinkTime)
// {
// elapsed += Time.deltaTime;
// float t = elapsed / sinkTime;
// spawnedShrine.transform.position = Vector3.Lerp(currentShrinePos, targetSinkPos, t);
//
// // Player từ từ hạ xuống sàn ban đầu
// float floorY = spawnedShrine.transform.position.y + shrineFloorOffset;
// if (floorY > playerStartPos.y)
// playerStateMachine.transform.position = new Vector3(playerStartPos.x, floorY, playerStartPos.z);
// else
// playerStateMachine.transform.position = playerStartPos;
//
// yield return null;
// }
// Destroy(spawnedShrine);
// }
//
// // 5. Thu nhỏ Volume
// float shrinkDuration = 0.5f;
// float sElapsed = 0;
// while (sElapsed < shrinkDuration)
// {
// sElapsed += Time.deltaTime;
// volumeCollider.radius = Mathf.Lerp(domainRadius, 0.1f, sElapsed / shrinkDuration);
// yield return null;
// }
// Destroy(volumeObj);
//
// // Dọn dẹp
// foreach (var s in activeSlashes) if (s != null) Destroy(s);
// activeSlashes.Clear();
//
// if (camController != null) camController.enabled = originalCamEnabled;
// playerStateMachine.SetControl(true);
// isActive = false;
// }
//
// private void SpawnRandomSlash(Vector3 center)
// {
// Vector2 randCircle = Random.insideUnitCircle * domainRadius;
// Vector3 spawnPos = center + new Vector3(randCircle.x, Random.Range(1f, 6f), randCircle.y);
//
// if (slashPrefab != null)
// {
// GameObject slash = Instantiate(slashPrefab, spawnPos, Random.rotation);
// slash.transform.localScale *= Random.Range(0.6f, 2.5f);
// activeSlashes.Add(slash);
// StartCoroutine(DestroySlashAfterTime(slash, 0.7f));
// }
// }
//
// private IEnumerator DestroySlashAfterTime(GameObject slash, float time)
// {
// yield return new WaitForSeconds(time);
// if (activeSlashes != null && activeSlashes.Contains(slash)) activeSlashes.Remove(slash);
// }
// }
// }

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 271dd39a46bad974485107bb1a070e0a

View File

@@ -1,27 +0,0 @@
using UnityEngine;
public class SukunaProjectile : MonoBehaviour
{
[Header("Movement")]
public float speed = 50f;
public float lifetime = 3f;
private Vector3 moveDirection;
public void SetDirection(Vector3 direction)
{
// Nhận hướng bay từ Player (luôn là hướng phía trước)
moveDirection = direction.normalized;
}
void Start()
{
Destroy(gameObject, lifetime);
}
void Update()
{
// Di chuyển đạn theo hướng đã gán, bất kể góc xoay hiển thị của nó là gì
transform.position += moveDirection * speed * Time.deltaTime;
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: b9b0aad9f1697954a9f8710b4e8f3f2e

View File

@@ -1,53 +0,0 @@
using UnityEngine;
public class SukunaSlashEffect : MonoBehaviour
{
[Header("Settings")]
public float duration = 0.2f;
public float maxScale = 5f;
public AnimationCurve scaleCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
[Header("Visuals")]
private MeshRenderer meshRenderer;
private MaterialPropertyBlock propBlock;
private float timer = 0f;
private static readonly int DissolveId = Shader.PropertyToID("_Dissolve");
void Awake()
{
meshRenderer = GetComponent<MeshRenderer>();
propBlock = new MaterialPropertyBlock();
}
void Start()
{
// Reset scale ban đầu
transform.localScale = new Vector3(maxScale, 0.1f, 0.1f);
}
void Update()
{
timer += Time.deltaTime;
float normalizedTime = timer / duration;
if (normalizedTime <= 1.0f)
{
// Mở rộng vệt chém theo chiều ngang (Y hoặc Z tùy mesh)
float currentScaleY = scaleCurve.Evaluate(normalizedTime) * maxScale;
transform.localScale = new Vector3(maxScale, currentScaleY, 1f);
// Điều khiển Shader bằng MaterialPropertyBlock
if (meshRenderer != null)
{
meshRenderer.GetPropertyBlock(propBlock);
propBlock.SetFloat(DissolveId, normalizedTime);
meshRenderer.SetPropertyBlock(propBlock);
}
}
else
{
// Tự hủy sau khi xong
Destroy(gameObject);
}
}
}

View File

@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 66ad11f71e7aac841be73f4b03cf0d83

View File

@@ -1,19 +0,0 @@
{
"name": "Opsive.UltimateCharacterController.Editor",
"references": [
"Opsive.UltimateCharacterController",
"Opsive.Shared",
"Opsive.Shared.Editor",
"Unity.InputSystem"
],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}

View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: 20dfc4c7578775b408501a7e6bd820e7
timeCreated: 1545599552
licenseType: Pro
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More