Files
Learning-UnityNGO/Assets/CONTENT/FEATURES/DEV-TEST/Scripts/UI/MainMenuUIController.cs
T

144 lines
4.7 KiB
C#

using System;
using Unity.Netcode;
using Unity.Services.Multiplayer;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using TMPro;
public class MainMenuUIController : MonoBehaviour
{
[Header("Buttons")]
[SerializeField] private Button hostButton;
[SerializeField] private Button clientButton;
[Header("Join by code")]
[SerializeField] private TMP_InputField joinCodeInput;
[Header("Feedback")]
[SerializeField] private TMP_Text joinCodeDisplay; // показывает код созданной сессии
[SerializeField] private TMP_Text statusText; // статус/ошибки
[SerializeField] private Button copyCodeButton; // копирование кода в буфер обмена
[Header("Session")]
[SerializeField] private int maxPlayers = 2;
[SerializeField] private string sessionType = "dev-game";
[SerializeField] private string gameSceneName = "DEV-Game";
private ISession session;
private bool isBusy;
private void Awake()
{
hostButton.onClick.AddListener(OnHostClicked);
clientButton.onClick.AddListener(OnJoinClicked);
if (copyCodeButton != null)
{
copyCodeButton.onClick.AddListener(CopyCode);
copyCodeButton.gameObject.SetActive(false);
}
}
private void OnDestroy()
{
hostButton.onClick.RemoveListener(OnHostClicked);
clientButton.onClick.RemoveListener(OnJoinClicked);
if (copyCodeButton != null)
copyCodeButton.onClick.RemoveListener(CopyCode);
}
private void CopyCode()
{
if (string.IsNullOrEmpty(SessionInfo.JoinCode)) return;
GUIUtility.systemCopyBuffer = SessionInfo.JoinCode;
SetStatus($"Code copied: {SessionInfo.JoinCode}");
}
private async void OnHostClicked()
{
if (isBusy) return;
SetBusy(true);
SetStatus("Creating session...");
try
{
SessionOptions _options = new SessionOptions
{
Name = $"session-{Guid.NewGuid().ToString().Substring(0, 6)}",
MaxPlayers = maxPlayers,
Type = sessionType
};
_options.WithRelayNetwork();
// Sessions API сам поднимает Relay и запускает NetworkManager как host
session = await MultiplayerService.Instance.CreateSessionAsync(_options);
SessionInfo.JoinCode = session.Code;
if (joinCodeDisplay != null) joinCodeDisplay.text = session.Code;
if (copyCodeButton != null) copyCodeButton.gameObject.SetActive(true);
SetStatus($"Hosting. Code: {session.Code}");
Debug.Log($"Session created. Join code: {session.Code}");
// Хост грузит игровую сцену — клиентам она синхронизируется автоматически.
// Код сохранён в SessionInfo и показывается уже в игре (SessionCodeView).
NetworkManager.Singleton.SceneManager.LoadScene(gameSceneName, LoadSceneMode.Single);
}
catch (Exception _e)
{
SetStatus($"Host failed: {_e.Message}");
Debug.LogException(_e);
SetBusy(false);
}
}
private async void OnJoinClicked()
{
if (isBusy) return;
string _code = joinCodeInput != null ? joinCodeInput.text.Trim() : string.Empty;
if (string.IsNullOrEmpty(_code))
{
SetStatus("Enter a join code first");
return;
}
SetBusy(true);
SetStatus($"Joining {_code}...");
try
{
JoinSessionOptions _options = new JoinSessionOptions { Type = sessionType };
// Подключение к Relay и запуск NetworkManager как client — автоматически.
// Игровая сцена придёт от хоста через сетевую синхронизацию сцен.
session = await MultiplayerService.Instance.JoinSessionByCodeAsync(_code, _options);
SessionInfo.JoinCode = _code;
SetStatus("Joined. Waiting for host scene...");
Debug.Log($"Joined session {session.Id}");
}
catch (Exception _e)
{
SetStatus($"Join failed: {_e.Message}");
Debug.LogException(_e);
SetBusy(false);
}
}
private void SetBusy(bool _busy)
{
isBusy = _busy;
hostButton.interactable = !_busy;
clientButton.interactable = !_busy;
}
private void SetStatus(string _text)
{
if (statusText != null) statusText.text = _text;
}
}