update MUTIPLAY
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
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;
|
||||
|
||||
// ĐỊNH NGHĨA DỮ LIỆU GỬI QUA MẠNG
|
||||
public struct NetworkInputData : INetworkInput
|
||||
// Struct input đồng bộ giữa Spawner, Movement và StateMachine
|
||||
public struct PlayerInputData : INetworkInput
|
||||
{
|
||||
public Vector2 move;
|
||||
public Vector2 Direction;
|
||||
public Quaternion rot;
|
||||
public bool sprint;
|
||||
}
|
||||
@@ -17,30 +20,80 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
|
||||
{
|
||||
private NetworkRunner _runner;
|
||||
|
||||
public LobbyManager LobbyManager;
|
||||
[SerializeField] private NetworkPrefabRef _playerPrefab;
|
||||
private Dictionary<PlayerRef, NetworkObject> _spawnedCharacters = new Dictionary<PlayerRef, NetworkObject>();
|
||||
|
||||
async void StartGame(GameMode mode)
|
||||
// Thông tin profile local
|
||||
public PlayerProfile LocalPlayerProfile { get; private set; }
|
||||
public void SetLocalPlayerProfile(PlayerProfile profile)
|
||||
{
|
||||
if (_runner != null) return;
|
||||
_runner = gameObject.AddComponent<NetworkRunner>();
|
||||
_runner.ProvideInput = true;
|
||||
LocalPlayerProfile = profile;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (_runner == null) _runner = gameObject.AddComponent<NetworkRunner>();
|
||||
DontDestroyOnLoad(gameObject);
|
||||
await _runner.StartGame(new StartGameArgs()
|
||||
}
|
||||
|
||||
// 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 = "TestRoom",
|
||||
SessionName = sessionName,
|
||||
Scene = SceneRef.FromIndex(1),
|
||||
SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()
|
||||
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)
|
||||
if (_runner == null || !_runner.IsRunning)
|
||||
{
|
||||
if (GUI.Button(new Rect(10, 10, 200, 40), "Host (Tạo phòng)")) StartGame(GameMode.AutoHostOrClient);
|
||||
if (GUI.Button(new Rect(10, 60, 200, 40), "Join (Vào phòng)")) StartGame(GameMode.Client);
|
||||
if (GUI.Button(new Rect(10, 10, 250, 40), "Bắt đầu (Auto Host/Client)"))
|
||||
{
|
||||
_ = StartGame(GameMode.AutoHostOrClient);
|
||||
}
|
||||
GUI.Label(new Rect(10, 60, 300, 20), "Gợi ý: Mở bản Build trước, sau đó mở Unity bấm nút trên.");
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,34 +101,15 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
|
||||
{
|
||||
if (runner.IsServer)
|
||||
{
|
||||
Vector3 spawnPosition = new Vector3((player.RawEncoded % 10) * 2, 1, 0);
|
||||
NetworkObject networkPlayerObject = runner.Spawn(_playerPrefab, spawnPosition, Quaternion.identity, player);
|
||||
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 OnInput(NetworkRunner runner, NetworkInput input)
|
||||
{
|
||||
var data = new NetworkInputData();
|
||||
|
||||
// Lấy dữ liệu từ nhân vật local của chính mình
|
||||
if (OnlyScove.Scripts.PlayerStateMachine.Local != null)
|
||||
{
|
||||
var sm = OnlyScove.Scripts.PlayerStateMachine.Local;
|
||||
data.move = sm.Input.MoveInput;
|
||||
data.sprint = sm.Input.IsSprintHeld;
|
||||
|
||||
// Lấy hướng xoay từ Camera (nếu có)
|
||||
if (sm.Cam != null)
|
||||
data.rot = sm.Cam.PlanarRotation;
|
||||
else
|
||||
data.rot = sm.NetworkedCameraRotation; // Fallback
|
||||
}
|
||||
|
||||
input.Set(data);
|
||||
}
|
||||
|
||||
public void OnPlayerLeft(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
if (_spawnedCharacters.TryGetValue(player, out NetworkObject networkObject))
|
||||
@@ -85,6 +119,29 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public void OnInputMissing(NetworkRunner runner, PlayerRef player, NetworkInput input) { }
|
||||
public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason) { }
|
||||
public void OnConnectedToServer(NetworkRunner runner) { }
|
||||
@@ -92,7 +149,6 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
|
||||
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 OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList) { }
|
||||
public void OnCustomAuthenticationResponse(NetworkRunner runner, Dictionary<string, object> data) { }
|
||||
public void OnHostMigration(NetworkRunner runner, HostMigrationToken hostMigrationToken) { }
|
||||
public void OnSceneLoadDone(NetworkRunner runner) { }
|
||||
@@ -101,4 +157,4 @@ public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
|
||||
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
Assets/Scripts/Fusion/LobbyHelper.cs
Normal file
1
Assets/Scripts/Fusion/LobbyHelper.cs
Normal file
@@ -0,0 +1 @@
|
||||
// File này hiện tại không còn nội dung, có thể xóa đi hoặc để trống.
|
||||
2
Assets/Scripts/Fusion/LobbyHelper.cs.meta
Normal file
2
Assets/Scripts/Fusion/LobbyHelper.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bf2c7f159565794b87d6f3ca2eb2976
|
||||
28
Assets/Scripts/Fusion/LobbyManager.cs
Normal file
28
Assets/Scripts/Fusion/LobbyManager.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Fusion/LobbyManager.cs.meta
Normal file
2
Assets/Scripts/Fusion/LobbyManager.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5aeb4670d7bf41499d3aaf409820260
|
||||
17
Assets/Scripts/Fusion/PlayerProfile.cs
Normal file
17
Assets/Scripts/Fusion/PlayerProfile.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
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;
|
||||
}
|
||||
2
Assets/Scripts/Fusion/PlayerProfile.cs.meta
Normal file
2
Assets/Scripts/Fusion/PlayerProfile.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a1452ae101af8e43b94c2c778a70fe0
|
||||
Reference in New Issue
Block a user