Add a new PlayerSceneObject prefab with components including Camera, AudioListener, and MonoBehaviour. Create a TrooperNetwork asset to support network functionalities. These changes enhance the scene's interactivity and prepare for multiplayer features.
124 lines
4.6 KiB
C#
124 lines
4.6 KiB
C#
using TMPro;
|
||
using Unity.Netcode;
|
||
using UnityEngine;
|
||
using UnityEngine.SceneManagement;
|
||
|
||
public class GameManager : NetworkBehaviour
|
||
{
|
||
public static GameManager Instance;
|
||
|
||
[SerializeField] private TextMeshProUGUI _playerCountPlaceholder;
|
||
[SerializeField] private int _maxPlayers = 2; // Максимальное количество игроков
|
||
[SerializeField] private GameObject playerPrefab; // Префаб игрока
|
||
|
||
private NetworkVariable<int> _connectedPlayers = new NetworkVariable<int>(0); // Текущее количество подключенных игроков
|
||
|
||
void Awake()
|
||
{
|
||
if (Instance == null)
|
||
{
|
||
Instance = this;
|
||
DontDestroyOnLoad(gameObject); // Persist across scenes
|
||
}
|
||
else
|
||
{
|
||
Destroy(gameObject);
|
||
}
|
||
}
|
||
|
||
public override void OnNetworkSpawn()
|
||
{
|
||
if (IsServer)
|
||
{
|
||
// Подписываемся на событие подключения игроков
|
||
NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnected;
|
||
// Подписываемся на событие отключения игроков
|
||
NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnected;
|
||
// Подписываемся на событие смены сцены
|
||
NetworkManager.Singleton.SceneManager.OnSceneEvent += OnSceneEvent;
|
||
}
|
||
|
||
// Подписываемся на изменение количества игроков для обновления UI
|
||
_connectedPlayers.OnValueChanged += OnConnectedPlayersChanged;
|
||
|
||
// Initialize the UI with the current value of _connectedPlayers
|
||
_playerCountPlaceholder.text = $"Players: {_connectedPlayers.Value}";
|
||
}
|
||
|
||
public override void OnNetworkDespawn()
|
||
{
|
||
if (IsServer)
|
||
{
|
||
// Отписываемся от события подключения игроков
|
||
NetworkManager.Singleton.OnClientConnectedCallback -= OnClientConnected;
|
||
// Отписываемся от события отключения игроков
|
||
NetworkManager.Singleton.OnClientDisconnectCallback -= OnClientDisconnected;
|
||
// Отписываемся от события смены сцены
|
||
NetworkManager.Singleton.SceneManager.OnSceneEvent -= OnSceneEvent;
|
||
}
|
||
|
||
// Отписываемся от изменения количества игроков
|
||
_connectedPlayers.OnValueChanged -= OnConnectedPlayersChanged;
|
||
}
|
||
|
||
private void OnClientConnected(ulong clientId)
|
||
{
|
||
if (IsServer)
|
||
{
|
||
_connectedPlayers.Value++;
|
||
Debug.Log($"Игрок подключился: {clientId}, Всего игроков: {_connectedPlayers.Value}");
|
||
|
||
// Если все игроки подключены, начинаем матч
|
||
if (_connectedPlayers.Value >= _maxPlayers)
|
||
{
|
||
StartMatchServerRpc();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void OnClientDisconnected(ulong clientId)
|
||
{
|
||
if (IsServer)
|
||
{
|
||
_connectedPlayers.Value--;
|
||
Debug.Log($"Игрок отключился: {clientId}, Всего игроков: {_connectedPlayers.Value}");
|
||
}
|
||
}
|
||
|
||
private void OnConnectedPlayersChanged(int oldValue, int newValue)
|
||
{
|
||
// Обновляем UI для всех клиентов
|
||
_playerCountPlaceholder.text = $"Players: {newValue}";
|
||
}
|
||
|
||
[ServerRpc(RequireOwnership = false)]
|
||
public void StartMatchServerRpc()
|
||
{
|
||
Debug.Log("Матч начался!");
|
||
|
||
if (NetworkManager.Singleton != null && NetworkManager.Singleton.SceneManager != null)
|
||
{
|
||
// Загружаем сцену MultiplayerScene
|
||
NetworkManager.Singleton.SceneManager.LoadScene("MultiplayerScene", LoadSceneMode.Single);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("NetworkManager или SceneManager не инициализированы!");
|
||
}
|
||
}
|
||
|
||
private void OnSceneEvent(SceneEvent sceneEvent)
|
||
{
|
||
if (sceneEvent.SceneEventType == SceneEventType.LoadComplete)
|
||
{
|
||
Debug.Log($"Сцена {sceneEvent.SceneName} загружена!");
|
||
|
||
// Создаем игроков после загрузки сцены
|
||
foreach (var client in NetworkManager.Singleton.ConnectedClientsList)
|
||
{
|
||
var playerObject = Instantiate(playerPrefab);
|
||
playerObject.GetComponent<NetworkObject>().SpawnAsPlayerObject(client.ClientId);
|
||
}
|
||
}
|
||
}
|
||
} |