Elo system update
This commit is contained in:
21
.idea/.idea.HALLUCINATE/.idea/workspace.xml
generated
21
.idea/.idea.HALLUCINATE/.idea/workspace.xml
generated
@@ -6,12 +6,25 @@
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="f9183c68-daf0-43b8-be4c-fad79983f91b" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.HALLUCINATE/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.HALLUCINATE/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Duy/PlayerInputData.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Duy/PlayerInputData.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Duy/_BasicSpawner.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Duy/_BasicSpawner.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Duy/_PlayerDataManager.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Duy/_PlayerDataManager.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Fusion.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Fusion/BasicSpawner.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Fusion/BasicSpawner.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Fusion/LobbyHelper.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Fusion/LobbyHelper.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Fusion/LobbyManager.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Fusion/LobbyManager.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Fusion/PlayerProfile.cs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Fusion/PlayerProfile.cs.meta" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerStateMachine.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerStateMachine.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerStats.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Player Controller/PlayerStats.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/BaseUIController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/BaseUIController.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/HUDController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/HUDController.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/LobbyController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/LobbyController.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/MainMenuController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/MainMenuController.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/SettingsController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/SettingsController.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/UIManager.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/UIManager.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/UI/Global.uss" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/UI/Global.uss" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/UI/MainPanelSettings.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/UI/MainPanelSettings.asset" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -149,7 +162,7 @@
|
||||
<workItem from="1777269364664" duration="40284000" />
|
||||
<workItem from="1777373072815" duration="1852000" />
|
||||
<workItem from="1777376778745" duration="10727000" />
|
||||
<workItem from="1777392719306" duration="11529000" />
|
||||
<workItem from="1777392719306" duration="13382000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
using Fusion;
|
||||
using UnityEngine;
|
||||
|
||||
public partial struct _PlayerInputData : INetworkInput
|
||||
namespace OnlyScove.Scripts
|
||||
{
|
||||
public float direction;
|
||||
}
|
||||
public struct PlayerInputData : INetworkInput
|
||||
{
|
||||
public Vector2 Direction;
|
||||
public NetworkBool sprint;
|
||||
public Quaternion rot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
||||
using Fusion;
|
||||
using Fusion.Sockets;
|
||||
using UnityEngine;
|
||||
using OnlyScove.Scripts;
|
||||
|
||||
namespace Hallucinate.UI
|
||||
{
|
||||
@@ -42,7 +43,6 @@ namespace Hallucinate.UI
|
||||
{
|
||||
OnJoinStartedEvent?.Invoke();
|
||||
|
||||
// Sử dụng SessionProperties để lưu mật khẩu
|
||||
var customProps = new Dictionary<string, SessionProperty>();
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
@@ -88,13 +88,6 @@ namespace Hallucinate.UI
|
||||
|
||||
public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
if (runner.IsServer)
|
||||
{
|
||||
Vector2 spawnPosition = (player == runner.LocalPlayer) ? new Vector2(-8, 0) : new Vector2(8, 0);
|
||||
var networkPlayerObject = runner.Spawn(_playerPrefab, spawnPosition, Quaternion.identity, player);
|
||||
_spawnedCharacters.Add(player, networkPlayerObject);
|
||||
}
|
||||
|
||||
if (player == runner.LocalPlayer)
|
||||
{
|
||||
var pdm = FindFirstObjectByType<_PlayerDataManager>();
|
||||
@@ -104,12 +97,21 @@ namespace Hallucinate.UI
|
||||
{
|
||||
Name = LocalPlayerProfile.Name,
|
||||
Role = LocalPlayerProfile.Role,
|
||||
IsReady = false
|
||||
};
|
||||
pdm.RPC_UpdatePlayerMetaData(player, metaData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void StartGame()
|
||||
{
|
||||
if (_runner.IsServer)
|
||||
{
|
||||
_runner.LoadScene("Main Scene");
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPlayerLeft(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
if (_spawnedCharacters.TryGetValue(player, out NetworkObject networkObject))
|
||||
@@ -132,8 +134,27 @@ namespace Hallucinate.UI
|
||||
|
||||
public void OnInput(NetworkRunner runner, NetworkInput input)
|
||||
{
|
||||
var data = new _PlayerInputData();
|
||||
data.direction = Input.GetAxis("Vertical");
|
||||
var data = new PlayerInputData();
|
||||
|
||||
// Try to get input from the local player's InputReader
|
||||
if (PlayerStateMachine.Local != null && PlayerStateMachine.Local.Input != null)
|
||||
{
|
||||
var inputReader = PlayerStateMachine.Local.Input;
|
||||
data.Direction = inputReader.MoveInput;
|
||||
data.sprint = inputReader.IsSprintHeld;
|
||||
|
||||
if (PlayerStateMachine.Local.Cam != null)
|
||||
{
|
||||
data.rot = PlayerStateMachine.Local.Cam.PlanarRotation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback to basic input if player not spawned or InputReader missing
|
||||
data.Direction = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
|
||||
data.sprint = Input.GetKey(KeyCode.LeftShift);
|
||||
}
|
||||
|
||||
input.Set(data);
|
||||
}
|
||||
|
||||
@@ -149,7 +170,31 @@ namespace Hallucinate.UI
|
||||
public void OnObjectEnterAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player) { }
|
||||
public void OnCustomAuthenticationResponse(NetworkRunner runner, Dictionary<string, object> data) { }
|
||||
public void OnHostMigration(NetworkRunner runner, HostMigrationToken hostMigrationToken) { }
|
||||
public void OnSceneLoadDone(NetworkRunner runner) { }
|
||||
|
||||
public void OnSceneLoadDone(NetworkRunner runner)
|
||||
{
|
||||
string currentSceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
|
||||
|
||||
if (runner.IsServer && currentSceneName == "Main Scene")
|
||||
{
|
||||
foreach (var player in runner.ActivePlayers)
|
||||
{
|
||||
Vector2 spawnPosition = (player == runner.LocalPlayer) ? new Vector2(-8, 0) : new Vector2(8, 0);
|
||||
var networkPlayerObject = runner.Spawn(_playerPrefab, spawnPosition, Quaternion.identity, player);
|
||||
_spawnedCharacters.Add(player, networkPlayerObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentSceneName == "Main Scene")
|
||||
{
|
||||
if (UIManager.Instance != null) UIManager.Instance.OnGameStarted();
|
||||
}
|
||||
else if (currentSceneName == "Lobby" || currentSceneName == "Menu")
|
||||
{
|
||||
if (UIManager.Instance != null) UIManager.Instance.OnBackToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSceneLoadStart(NetworkRunner runner) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,23 +6,29 @@ public struct _PlayerMetaData : INetworkStruct
|
||||
{
|
||||
public NetworkString<_16> Name;
|
||||
public _Role Role;
|
||||
public NetworkBool IsReady;
|
||||
}
|
||||
|
||||
public class _PlayerDataManager : NetworkBehaviour
|
||||
{
|
||||
// biến này của Fusion sẽ tự động đồng bộ giữa các client và host,
|
||||
// khi có thay đổi sẽ tự động cập nhật ở tất cả các bên
|
||||
[Networked]
|
||||
public NetworkDictionary<PlayerRef, _PlayerMetaData> Players => default;
|
||||
|
||||
// RPC: phương thức này sẽ được gọi từ client hoặc
|
||||
// host để cập nhật thông tin player, sau đó sẽ được gửi
|
||||
// đến state authority (host) để xử lý và đồng bộ lại cho tất cả các client
|
||||
[Rpc(RpcSources.All, RpcTargets.StateAuthority)]
|
||||
public void RPC_UpdatePlayerMetaData(PlayerRef playerRef, _PlayerMetaData metaData)
|
||||
{
|
||||
Players.Set(playerRef, metaData);
|
||||
}
|
||||
|
||||
[Rpc(RpcSources.All, RpcTargets.StateAuthority)]
|
||||
public void RPC_SetReady(PlayerRef playerRef, bool ready)
|
||||
{
|
||||
if (Players.TryGet(playerRef, out var data))
|
||||
{
|
||||
data.IsReady = ready;
|
||||
Players.Set(playerRef, data);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetPlayerMetaData(PlayerRef playerRef, out _PlayerMetaData metaData)
|
||||
{
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using Fusion;
|
||||
using Fusion.Sockets;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
// Struct input đồng bộ giữa Spawner, Movement và StateMachine
|
||||
public struct PlayerInputData : INetworkInput
|
||||
{
|
||||
public Vector2 Direction;
|
||||
public Quaternion rot;
|
||||
public bool sprint;
|
||||
}
|
||||
|
||||
public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
|
||||
{
|
||||
private NetworkRunner _runner;
|
||||
private string _roomName = "Room1";
|
||||
|
||||
public LobbyManager LobbyManager;
|
||||
[SerializeField] private NetworkPrefabRef _playerPrefab;
|
||||
private Dictionary<PlayerRef, NetworkObject> _spawnedCharacters = new Dictionary<PlayerRef, NetworkObject>();
|
||||
|
||||
// Thông tin profile local
|
||||
public PlayerProfile LocalPlayerProfile { get; private set; }
|
||||
public void SetLocalPlayerProfile(PlayerProfile profile)
|
||||
{
|
||||
LocalPlayerProfile = profile;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (_runner == null) _runner = gameObject.AddComponent<NetworkRunner>();
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
// Khởi tạo Game (Host/Client)
|
||||
public async Task StartGame(GameMode mode, string sessionName = "TestRoom")
|
||||
{
|
||||
Debug.Log($"<color=yellow>Fusion:</color> Đang khởi tạo kết nối với Mode: {mode} | Phòng: {sessionName}");
|
||||
|
||||
if (_runner == null) _runner = gameObject.AddComponent<NetworkRunner>();
|
||||
_runner.ProvideInput = true;
|
||||
|
||||
var sceneManager = gameObject.GetComponent<NetworkSceneManagerDefault>();
|
||||
if (sceneManager == null) sceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>();
|
||||
|
||||
var result = await _runner.StartGame(new StartGameArgs()
|
||||
{
|
||||
GameMode = mode,
|
||||
SessionName = sessionName,
|
||||
Scene = SceneRef.FromIndex(1),
|
||||
SceneManager = sceneManager
|
||||
});
|
||||
|
||||
if (result.Ok)
|
||||
{
|
||||
Debug.Log($"<color=green>Fusion thành công:</color> Đã vào phòng {sessionName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"<color=red>Fusion thất bại:</color> Lý do: {result.ShutdownReason}");
|
||||
if (_runner != null)
|
||||
{
|
||||
Destroy(_runner);
|
||||
_runner = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (_runner == null || !_runner.IsRunning)
|
||||
{
|
||||
float width = 400;
|
||||
float height = 300;
|
||||
float x = (Screen.width - width) / 2f;
|
||||
float y = (Screen.height - height) / 2f;
|
||||
|
||||
GUI.Box(new Rect(x, y, width, height), "FUSION MULTIPLAYER");
|
||||
|
||||
float innerX = x + 20;
|
||||
float innerY = y + 40;
|
||||
float contentWidth = width - 40;
|
||||
|
||||
GUI.Label(new Rect(innerX, innerY, 100, 30), "Tên phòng:");
|
||||
_roomName = GUI.TextField(new Rect(innerX + 100, innerY, contentWidth - 100, 30), _roomName);
|
||||
|
||||
if (GUI.Button(new Rect(innerX, innerY + 50, contentWidth, 60), "VÀO PHÒNG\n(Tự động Host/Client)"))
|
||||
{
|
||||
_ = StartGame(GameMode.AutoHostOrClient, _roomName);
|
||||
}
|
||||
|
||||
if (GUI.Button(new Rect(innerX, innerY + 120, (contentWidth / 2) - 5, 50), "Tạo phòng\n(Host)"))
|
||||
{
|
||||
_ = StartGame(GameMode.Host, _roomName);
|
||||
}
|
||||
|
||||
if (GUI.Button(new Rect(innerX + (contentWidth / 2) + 5, innerY + 120, (contentWidth / 2) - 5, 50), "Tham gia\n(Client)"))
|
||||
{
|
||||
_ = StartGame(GameMode.Client, _roomName);
|
||||
}
|
||||
|
||||
GUI.Label(new Rect(innerX, innerY + 180, contentWidth, 50), "Gợi ý: Nhập cùng tên phòng để chơi chung.\nNếu phòng chưa có, máy sẽ tự tạo mới.");
|
||||
}
|
||||
else
|
||||
{
|
||||
string region = (_runner.SessionInfo != null && _runner.SessionInfo.IsValid) ? _runner.SessionInfo.Region : "Connecting...";
|
||||
int playerCount = 0;
|
||||
foreach (var p in _runner.ActivePlayers) playerCount++;
|
||||
|
||||
string info = $"Mode: {_runner.GameMode} | Region: {region} | Players: {playerCount}";
|
||||
GUI.Box(new Rect(10, 10, 400, 30), info);
|
||||
|
||||
if (GUI.Button(new Rect(10, 50, 100, 30), "Thoát"))
|
||||
{
|
||||
_runner.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
if (runner.IsServer)
|
||||
{
|
||||
Vector3 spawnPosition = new Vector3(Random.Range(-10f, 10f), 2f, Random.Range(-10f, 10f));
|
||||
spawnPosition += new Vector3(player.RawEncoded % 3, 0, player.RawEncoded % 3);
|
||||
|
||||
var networkPlayerObject = runner.Spawn(_playerPrefab, spawnPosition, Quaternion.identity, player);
|
||||
runner.SetPlayerObject(player, networkPlayerObject);
|
||||
_spawnedCharacters.Add(player, networkPlayerObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPlayerLeft(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
if (_spawnedCharacters.TryGetValue(player, out NetworkObject networkObject))
|
||||
{
|
||||
if (networkObject != null) runner.Despawn(networkObject);
|
||||
_spawnedCharacters.Remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnInput(NetworkRunner runner, NetworkInput input)
|
||||
{
|
||||
var data = new PlayerInputData();
|
||||
|
||||
// ĐỌC TRỰC TIẾP: Không dùng Buffer để tránh bị trôi phím
|
||||
data.Direction = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
|
||||
data.sprint = Input.GetKey(KeyCode.LeftShift);
|
||||
|
||||
if (OnlyScove.Scripts.PlayerStateMachine.Local != null)
|
||||
{
|
||||
var sm = OnlyScove.Scripts.PlayerStateMachine.Local;
|
||||
if (sm.Cam != null) data.rot = sm.Cam.PlanarRotation;
|
||||
else data.rot = sm.NetworkedCameraRotation;
|
||||
}
|
||||
|
||||
input.Set(data);
|
||||
}
|
||||
|
||||
public void OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList)
|
||||
{
|
||||
if (LobbyManager != null) LobbyManager.DisplayRoomList(sessionList);
|
||||
// UI.UIEventBus.TriggerRoomListUpdate();
|
||||
}
|
||||
|
||||
public void OnInputMissing(NetworkRunner runner, PlayerRef player, NetworkInput input) { }
|
||||
public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason) { }
|
||||
public void OnConnectedToServer(NetworkRunner runner) { }
|
||||
public void OnDisconnectedFromServer(NetworkRunner runner, NetDisconnectReason reason) { }
|
||||
public void OnConnectRequest(NetworkRunner runner, NetworkRunnerCallbackArgs.ConnectRequest request, byte[] token) { }
|
||||
public void OnConnectFailed(NetworkRunner runner, NetAddress remoteAddress, NetConnectFailedReason reason) { }
|
||||
public void OnUserSimulationMessage(NetworkRunner runner, SimulationMessagePtr message) { }
|
||||
public void OnCustomAuthenticationResponse(NetworkRunner runner, Dictionary<string, object> data) { }
|
||||
public void OnHostMigration(NetworkRunner runner, HostMigrationToken hostMigrationToken) { }
|
||||
public void OnSceneLoadDone(NetworkRunner runner) { }
|
||||
public void OnSceneLoadStart(NetworkRunner runner) { }
|
||||
public void OnObjectExitAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player) { }
|
||||
public void OnObjectEnterAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player) { }
|
||||
public void OnReliableDataReceived(NetworkRunner runner, PlayerRef player, ReliableKey key, ArraySegment<byte> data) { }
|
||||
public void OnReliableDataProgress(NetworkRunner runner, PlayerRef player, ReliableKey key, float progress) { }
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44bfaa339c82069418e72a14479a0212
|
||||
@@ -1 +0,0 @@
|
||||
// File này hiện tại không còn nội dung, có thể xóa đi hoặc để trống.
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bf2c7f159565794b87d6f3ca2eb2976
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Fusion;
|
||||
using UnityEngine;
|
||||
|
||||
public class LobbyManager : MonoBehaviour
|
||||
{
|
||||
[Header("UI References")]
|
||||
public Transform roomListContent; // Ô chứa danh sách phòng (nếu có)
|
||||
|
||||
public void DisplayRoomList(List<SessionInfo> sessionList)
|
||||
{
|
||||
Debug.Log($"<color=green>Lobby Update:</color> Đang tìm thấy {sessionList.Count} phòng.");
|
||||
|
||||
// Xóa danh sách cũ (nếu bạn làm UI)
|
||||
/*
|
||||
foreach (Transform child in roomListContent) {
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
*/
|
||||
|
||||
// Hiển thị danh sách mới
|
||||
foreach (var session in sessionList)
|
||||
{
|
||||
Debug.Log($"- Phòng: {session.Name} | Người chơi: {session.PlayerCount}/{session.MaxPlayers}");
|
||||
// Ở đây bạn sẽ Instantiate các Button đại diện cho mỗi phòng
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5aeb4670d7bf41499d3aaf409820260
|
||||
@@ -1,17 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
// Enum các loại nhân vật
|
||||
public enum CharacterClass
|
||||
{
|
||||
Warrior,
|
||||
Mage,
|
||||
Archer
|
||||
}
|
||||
|
||||
// Lớp quản lý thông tin nhân vật local
|
||||
[System.Serializable]
|
||||
public class PlayerProfile
|
||||
{
|
||||
public string Name = "Player";
|
||||
public CharacterClass Class = CharacterClass.Warrior;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a1452ae101af8e43b94c2c778a70fe0
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6aa851b2c7ee553439ee0065f77665cb
|
||||
guid: 1a38893b1d8574b45bce269c39824bd6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
64
Assets/Scripts/Game/EloSystem.cs
Normal file
64
Assets/Scripts/Game/EloSystem.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using UnityEngine;
|
||||
using Fusion;
|
||||
|
||||
namespace Hallucinate.Game
|
||||
{
|
||||
public static class EloSystem
|
||||
{
|
||||
public static EloResult Calculate(
|
||||
int ratingA, int ratingB,
|
||||
int gamesPlayedA, int gamesPlayedB,
|
||||
float resultA) // 1=win, 0=lose, 0.5=draw
|
||||
{
|
||||
float eA = 1f / (1f + Mathf.Pow(10f, (ratingB - ratingA) / 400f));
|
||||
int kA = GetK(ratingA, gamesPlayedA);
|
||||
int kB = GetK(ratingB, gamesPlayedB);
|
||||
|
||||
int nA = Mathf.Max(100, Mathf.RoundToInt(ratingA + kA * (resultA - eA)));
|
||||
int nB = Mathf.Max(100, Mathf.RoundToInt(ratingB + kB * ((1 - resultA) - (1 - eA))));
|
||||
|
||||
return new EloResult(nA, nB, nA - ratingA, nB - ratingB);
|
||||
}
|
||||
|
||||
private static int GetK(int r, int g) =>
|
||||
g < 30 ? 40 : r < 1200 ? 32 : r < 2000 ? 24 : 16;
|
||||
|
||||
public static string GetRank(int rating)
|
||||
{
|
||||
if (rating < 800) return "Iron";
|
||||
if (rating < 1000) return "Bronze";
|
||||
if (rating < 1200) return "Silver";
|
||||
if (rating < 1500) return "Gold";
|
||||
if (rating < 1800) return "Platinum";
|
||||
if (rating < 2100) return "Diamond";
|
||||
return "Master";
|
||||
}
|
||||
|
||||
public static string GetRankColor(int rating)
|
||||
{
|
||||
if (rating < 800) return "#8A8A8A";
|
||||
if (rating < 1000) return "#CD7F32";
|
||||
if (rating < 1200) return "#C0C0C0";
|
||||
if (rating < 1500) return "#FFD700";
|
||||
if (rating < 1800) return "#4DC8A0";
|
||||
if (rating < 2100) return "#7B6EE8";
|
||||
return "#E84D8A";
|
||||
}
|
||||
}
|
||||
|
||||
public struct EloResult : INetworkStruct
|
||||
{
|
||||
public int NewRatingA;
|
||||
public int NewRatingB;
|
||||
public int DeltaA;
|
||||
public int DeltaB;
|
||||
|
||||
public EloResult(int nA, int nB, int dA, int dB)
|
||||
{
|
||||
NewRatingA = nA;
|
||||
NewRatingB = nB;
|
||||
DeltaA = dA;
|
||||
DeltaB = dB;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Game/EloSystem.cs.meta
Normal file
2
Assets/Scripts/Game/EloSystem.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 366843378ad652a41aeb5972186ebe18
|
||||
8
Assets/Scripts/Network.meta
Normal file
8
Assets/Scripts/Network.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f96029db35b52ba4182888a7f14d2ea7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
77
Assets/Scripts/Network/MatchResultManager.cs
Normal file
77
Assets/Scripts/Network/MatchResultManager.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using Fusion;
|
||||
using UnityEngine;
|
||||
using Hallucinate.Game;
|
||||
using Hallucinate.UI;
|
||||
using System.Linq;
|
||||
|
||||
namespace Hallucinate.Network
|
||||
{
|
||||
public class MatchResultManager : NetworkBehaviour
|
||||
{
|
||||
public static MatchResultManager Instance { get; private set; }
|
||||
|
||||
public override void Spawned()
|
||||
{
|
||||
if (Object.HasStateAuthority) Instance = this;
|
||||
}
|
||||
|
||||
[Rpc(RpcSources.StateAuthority, RpcTargets.All)]
|
||||
public void RPC_BroadcastResult(PlayerRef winner, EloResult eloResult)
|
||||
{
|
||||
Debug.Log($"Game Over! Winner: {winner}. Elo updated.");
|
||||
|
||||
// Update local Elo display and show Result UI
|
||||
if (Runner.LocalPlayer == winner)
|
||||
{
|
||||
ShowResultUI(true, eloResult.DeltaA, eloResult.NewRatingA);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowResultUI(false, eloResult.DeltaB, eloResult.NewRatingB);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowResultUI(bool isWin, int delta, int newRating)
|
||||
{
|
||||
var hud = FindFirstObjectByType<HUDController>();
|
||||
if (hud != null)
|
||||
{
|
||||
// In a real scenario, we might push a new Result screen
|
||||
// For now, let's assume HUD has a result panel
|
||||
Debug.Log($"RESULT: {(isWin ? "WIN" : "LOSS")} | Delta: {delta} | New Rating: {newRating}");
|
||||
|
||||
// Save to PlayerPrefs as a dummy "Server" persistence
|
||||
PlayerPrefs.SetInt("EloRating", newRating);
|
||||
int gamesPlayed = PlayerPrefs.GetInt("GamesPlayed", 0);
|
||||
PlayerPrefs.SetInt("GamesPlayed", gamesPlayed + 1);
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessMatchEnd(PlayerRef winner)
|
||||
{
|
||||
if (!Object.HasStateAuthority) return;
|
||||
|
||||
// Get ratings for both players
|
||||
// In a real game, these would come from the server/metadata
|
||||
int ratingA = PlayerPrefs.GetInt("EloRating", 1000);
|
||||
int ratingB = 1000; // Placeholder for opponent
|
||||
int gamesA = PlayerPrefs.GetInt("GamesPlayed", 0);
|
||||
int gamesB = 0; // Placeholder
|
||||
|
||||
float resultA = (Runner.LocalPlayer == winner) ? 1.0f : 0.0f;
|
||||
|
||||
EloResult elo = EloSystem.Calculate(ratingA, ratingB, gamesA, gamesB, resultA);
|
||||
|
||||
RPC_BroadcastResult(winner, elo);
|
||||
|
||||
// Shut down runner after some delay
|
||||
Invoke(nameof(ShutdownRunner), 5.0f);
|
||||
}
|
||||
|
||||
private void ShutdownRunner()
|
||||
{
|
||||
Runner.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Network/MatchResultManager.cs.meta
Normal file
2
Assets/Scripts/Network/MatchResultManager.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9eac0255d30a2bb40a43ff12cdcdf960
|
||||
@@ -146,14 +146,6 @@ namespace OnlyScove.Scripts
|
||||
bool isRunning = Runner != null && Runner.IsRunning;
|
||||
if (Object == null && isRunning) return;
|
||||
|
||||
// Proxy Sync
|
||||
if (isRunning && Movement.NetworkedPosition != Vector3.zero && !Object.HasInputAuthority)
|
||||
{
|
||||
Controller.enabled = false;
|
||||
transform.position = Movement.NetworkedPosition;
|
||||
Controller.enabled = true;
|
||||
}
|
||||
|
||||
if (GetInput(out PlayerInputData data))
|
||||
{
|
||||
MoveInput = data.Direction;
|
||||
@@ -175,10 +167,24 @@ namespace OnlyScove.Scripts
|
||||
currentState?.Tick(isRunning ? Runner.DeltaTime : Time.fixedDeltaTime);
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
public override void Render()
|
||||
{
|
||||
bool isRunning = Runner != null && Runner.IsRunning;
|
||||
if (isRunning && !Object.HasInputAuthority)
|
||||
{
|
||||
// Smooth interpolation for proxies
|
||||
if (Movement.NetworkedPosition != Vector3.zero)
|
||||
{
|
||||
transform.position = Vector3.Lerp(transform.position, Movement.NetworkedPosition, Runner.DeltaTime * 15f);
|
||||
}
|
||||
UpdateAnimator(Runner.DeltaTime);
|
||||
}
|
||||
else if (!isRunning)
|
||||
{
|
||||
UpdateAnimator(Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using UnityEngine;
|
||||
using Fusion;
|
||||
using System;
|
||||
using Hallucinate.Network;
|
||||
|
||||
namespace OnlyScove.Scripts
|
||||
{
|
||||
@@ -24,10 +25,23 @@ namespace OnlyScove.Scripts
|
||||
void OnHealthChangedRender()
|
||||
{
|
||||
OnHealthChanged?.Invoke(Health);
|
||||
|
||||
if (Health <= 0 && Object.HasStateAuthority)
|
||||
{
|
||||
// Find the other player as winner
|
||||
foreach (var player in Runner.ActivePlayers)
|
||||
{
|
||||
if (player != Object.InputAuthority)
|
||||
{
|
||||
MatchResultManager.Instance?.ProcessMatchEnd(player);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.HasInputAuthority)
|
||||
{
|
||||
// UI Placeholder: Trigger Health UI Change
|
||||
// Example: UI.UIEventBus.TriggerHealthChange(Health / 100f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +51,6 @@ namespace OnlyScove.Scripts
|
||||
if (Object.HasInputAuthority)
|
||||
{
|
||||
// UI Placeholder: Trigger Stamina UI Change
|
||||
// Example: UI.UIEventBus.TriggerStaminaChange(Stamina / 100f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ namespace Hallucinate.UI
|
||||
return key;
|
||||
}
|
||||
|
||||
public virtual void Update() { }
|
||||
|
||||
public virtual async Task PlayTransitionIn()
|
||||
{
|
||||
if (root == null) return;
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Hallucinate.UI
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
public override void Update()
|
||||
{
|
||||
if (!_isFaded && Time.time - _lastActionTime > FADE_TIMEOUT)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using UnityEngine.UIElements;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Fusion;
|
||||
using System.Linq;
|
||||
|
||||
namespace Hallucinate.UI
|
||||
{
|
||||
@@ -10,6 +11,7 @@ namespace Hallucinate.UI
|
||||
{
|
||||
private VisualTreeAsset _roomItemTemplate;
|
||||
private _BasicSpawner _spawner;
|
||||
private _PlayerDataManager _playerDataManager;
|
||||
|
||||
// Containers
|
||||
private VisualElement _joinContainer, _createContainer, _loungeContainer, _passOverlay;
|
||||
@@ -24,6 +26,11 @@ namespace Hallucinate.UI
|
||||
private Label _joinPassError;
|
||||
private SessionInfo _selectedSession;
|
||||
|
||||
// Lounge Elements
|
||||
private VisualElement _playerListContainer;
|
||||
private Button _readyBtn, _startBtn;
|
||||
private Label _loungeRoomName;
|
||||
|
||||
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
|
||||
{
|
||||
base.Initialize(uxmlRoot, manager);
|
||||
@@ -44,27 +51,63 @@ namespace Hallucinate.UI
|
||||
_joinPassInput = root.Q<TextField>("JoinPassInput");
|
||||
_joinPassError = root.Q<Label>("JoinPassError");
|
||||
|
||||
// Event Bindings
|
||||
root.Q<Button>("GoToCreateBtn").clicked += ShowCreate;
|
||||
root.Q<Button>("CancelCreateBtn").clicked += ShowJoin;
|
||||
root.Q<Button>("BackToMenuBtn").clicked += async () => await uiManager.Pop();
|
||||
root.Q<Button>("ConfirmCreateBtn").clicked += OnCreateRoomClicked;
|
||||
root.Q<Button>("ConfirmJoinBtn").clicked += OnConfirmPasswordClicked;
|
||||
root.Q<Button>("ClosePassBtn").clicked += () => _passOverlay.style.display = DisplayStyle.None;
|
||||
// Lounge Elements
|
||||
_playerListContainer = root.Q<VisualElement>("PlayerList");
|
||||
_readyBtn = root.Q<Button>("ReadyBtn");
|
||||
_startBtn = root.Q<Button>("StartBtn");
|
||||
_loungeRoomName = root.Q<Label>("LoungeRoomName");
|
||||
|
||||
_passToggle.RegisterValueChangedCallback(evt =>
|
||||
_roomPassInput.style.display = evt.newValue ? DisplayStyle.Flex : DisplayStyle.None);
|
||||
// Event Bindings
|
||||
var goToCreateBtn = root.Q<Button>("GoToCreateBtn");
|
||||
if (goToCreateBtn != null) goToCreateBtn.clicked += ShowCreate;
|
||||
|
||||
var cancelCreateBtn = root.Q<Button>("CancelCreateBtn");
|
||||
if (cancelCreateBtn != null) cancelCreateBtn.clicked += ShowJoin;
|
||||
|
||||
var backToMenuBtn = root.Q<Button>("BackToMenuBtn");
|
||||
if (backToMenuBtn != null) backToMenuBtn.clicked += async () => await uiManager.Pop();
|
||||
|
||||
var confirmCreateBtn = root.Q<Button>("ConfirmCreateBtn");
|
||||
if (confirmCreateBtn != null) confirmCreateBtn.clicked += OnCreateRoomClicked;
|
||||
|
||||
var confirmJoinBtn = root.Q<Button>("ConfirmJoinBtn");
|
||||
if (confirmJoinBtn != null) confirmJoinBtn.clicked += OnConfirmPasswordClicked;
|
||||
|
||||
var closePassBtn = root.Q<Button>("ClosePassBtn");
|
||||
if (closePassBtn != null) closePassBtn.clicked += () => { if(_passOverlay != null) _passOverlay.style.display = DisplayStyle.None; };
|
||||
|
||||
var leaveLoungeBtn = root.Q<Button>("LeaveLoungeBtn");
|
||||
if (leaveLoungeBtn != null) 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;
|
||||
});
|
||||
}
|
||||
|
||||
// Đăng ký sự kiện từ Spawner
|
||||
if (_spawner != null)
|
||||
{
|
||||
_spawner.OnSessionListUpdatedEvent += UpdateRoomList;
|
||||
_spawner.OnJoinFailedEvent += () => _joinPassError.style.display = DisplayStyle.Flex;
|
||||
_spawner.OnJoinStartedEvent += () => { /* Show loading if needed */ };
|
||||
}
|
||||
}
|
||||
|
||||
public void SetRoomTemplate(VisualTreeAsset template) => _roomItemTemplate = template;
|
||||
|
||||
public override async Task PlayTransitionIn()
|
||||
{
|
||||
await base.PlayTransitionIn();
|
||||
ShowJoin();
|
||||
}
|
||||
|
||||
public void ShowJoin()
|
||||
{
|
||||
_joinContainer.style.display = DisplayStyle.Flex;
|
||||
@@ -79,6 +122,16 @@ namespace Hallucinate.UI
|
||||
_createContainer.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
|
||||
private void ShowLounge(string roomName)
|
||||
{
|
||||
_joinContainer.style.display = DisplayStyle.None;
|
||||
_createContainer.style.display = DisplayStyle.None;
|
||||
_loungeContainer.style.display = DisplayStyle.Flex;
|
||||
_loungeRoomName.text = $"Room: {roomName}";
|
||||
|
||||
_playerDataManager = Object.FindFirstObjectByType<_PlayerDataManager>();
|
||||
}
|
||||
|
||||
private async void OnCreateRoomClicked()
|
||||
{
|
||||
string id = _roomIDInput.value.Trim();
|
||||
@@ -88,10 +141,12 @@ namespace Hallucinate.UI
|
||||
if (string.IsNullOrEmpty(id)) return;
|
||||
|
||||
await _spawner.StartHost(id, pass);
|
||||
ShowLounge(name);
|
||||
}
|
||||
|
||||
private void UpdateRoomList(List<SessionInfo> sessions)
|
||||
{
|
||||
if (_roomList == null) return;
|
||||
_roomList.Clear();
|
||||
foreach (var session in sessions)
|
||||
{
|
||||
@@ -111,17 +166,111 @@ namespace Hallucinate.UI
|
||||
|
||||
private void OnRoomItemClicked(SessionInfo session)
|
||||
{
|
||||
_selectedSession = session;
|
||||
_passOverlay.style.display = DisplayStyle.Flex;
|
||||
_joinPassError.style.display = DisplayStyle.None;
|
||||
_joinPassInput.value = "";
|
||||
bool needsPass = session.Properties.ContainsKey("pw");
|
||||
if (needsPass)
|
||||
{
|
||||
_selectedSession = session;
|
||||
_passOverlay.style.display = DisplayStyle.Flex;
|
||||
_joinPassError.style.display = DisplayStyle.None;
|
||||
_joinPassInput.value = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
JoinRoom(session.Name, null);
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnConfirmPasswordClicked()
|
||||
{
|
||||
if (_selectedSession == null) return;
|
||||
string pass = _joinPassInput.value;
|
||||
await _spawner.StartClient(_selectedSession.Name, pass);
|
||||
_passOverlay.style.display = DisplayStyle.None;
|
||||
await JoinRoom(_selectedSession.Name, pass);
|
||||
}
|
||||
|
||||
private async Task JoinRoom(string sessionName, string password)
|
||||
{
|
||||
await _spawner.StartClient(sessionName, password);
|
||||
ShowLounge(sessionName);
|
||||
}
|
||||
|
||||
private void OnReadyClicked()
|
||||
{
|
||||
if (_playerDataManager != null)
|
||||
{
|
||||
var runner = Object.FindFirstObjectByType<NetworkRunner>();
|
||||
if (runner != null)
|
||||
{
|
||||
_playerDataManager.TryGetPlayerMetaData(runner.LocalPlayer, out var myData);
|
||||
_playerDataManager.RPC_SetReady(runner.LocalPlayer, !myData.IsReady);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStartClicked()
|
||||
{
|
||||
_spawner.StartGame();
|
||||
}
|
||||
|
||||
private void OnLeaveLoungeClicked()
|
||||
{
|
||||
var runner = Object.FindFirstObjectByType<NetworkRunner>();
|
||||
runner?.Shutdown();
|
||||
ShowJoin();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (_loungeContainer.style.display == DisplayStyle.Flex)
|
||||
{
|
||||
UpdateLoungeUI();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLoungeUI()
|
||||
{
|
||||
if (_playerDataManager == null)
|
||||
{
|
||||
_playerDataManager = Object.FindFirstObjectByType<_PlayerDataManager>();
|
||||
return;
|
||||
}
|
||||
|
||||
var runner = Object.FindFirstObjectByType<NetworkRunner>();
|
||||
if (runner == null) return;
|
||||
|
||||
// Update Player List
|
||||
_playerListContainer.Clear();
|
||||
bool allReady = true;
|
||||
int playerCount = 0;
|
||||
|
||||
foreach (var kvp in _playerDataManager.Players)
|
||||
{
|
||||
playerCount++;
|
||||
var playerRef = kvp.Key;
|
||||
var data = kvp.Value;
|
||||
|
||||
var playerItem = new VisualElement();
|
||||
playerItem.style.flexDirection = FlexDirection.Row;
|
||||
playerItem.style.justifyContent = Justify.SpaceBetween;
|
||||
playerItem.style.paddingBottom = 5;
|
||||
|
||||
var nameLabel = new Label(data.Name.ToString());
|
||||
var readyLabel = new Label(data.IsReady ? "READY" : "WAITING...");
|
||||
readyLabel.style.color = data.IsReady ? Color.green : Color.yellow;
|
||||
|
||||
playerItem.Add(nameLabel);
|
||||
playerItem.Add(readyLabel);
|
||||
_playerListContainer.Add(playerItem);
|
||||
|
||||
if (!data.IsReady) allReady = false;
|
||||
}
|
||||
|
||||
// Update Buttons
|
||||
_startBtn.style.display = (runner.IsServer && allReady && playerCount >= 2) ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
|
||||
_playerDataManager.TryGetPlayerMetaData(runner.LocalPlayer, out var myData);
|
||||
_readyBtn.text = myData.IsReady ? "UNREADY" : "READY UP";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ namespace Hallucinate.UI
|
||||
.OnComplete(() => _ribbon.style.display = DisplayStyle.None);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
public override void Update()
|
||||
{
|
||||
if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0 || Input.anyKey)
|
||||
{
|
||||
|
||||
@@ -65,13 +65,30 @@ namespace Hallucinate.UI
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
|
||||
_uiDocument = GetComponent<UIDocument>();
|
||||
UnityEngine.Cursor.visible = false;
|
||||
|
||||
ApplySavedUIScale();
|
||||
}
|
||||
|
||||
public void OnGameStarted()
|
||||
{
|
||||
_ = Push<HUDController>();
|
||||
}
|
||||
|
||||
public void OnBackToMenu()
|
||||
{
|
||||
_ = Push<MainMenuController>();
|
||||
}
|
||||
|
||||
public void SetUIScale(float scale)
|
||||
{
|
||||
if (_uiDocument == null || _uiDocument.panelSettings == null) return;
|
||||
@@ -187,7 +204,7 @@ namespace Hallucinate.UI
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_mainMenuController != null) _mainMenuController.Update();
|
||||
if (_history.Count > 0) _history.Peek().Update();
|
||||
UpdateCursorAndTrail();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user