using FishNet; using FishNet.Discovery; using System.Collections; using System.Collections.Generic; using System.Net; using TMPro; using UnityEngine; using UnityEngine.UI; public class NetworkMenuUI : MonoBehaviour { [Header("UI References")] public Button startPlayingButton; public Button joinMultiplayerButton; public Transform serverListContainer; public GameObject serverListItemPrefab; public TMP_Text statusText; [Header("Networking")] public NetworkDiscovery networkDiscovery; public Camera uiCamera; // Optional, disable if connecting private readonly List<IPEndPoint> foundServers = new(); private void Start() { if (networkDiscovery == null) networkDiscovery = FindObjectOfType<NetworkDiscovery>(); startPlayingButton.onClick.AddListener(OnStartPlaying); joinMultiplayerButton.onClick.AddListener(OnJoinMultiplayer); networkDiscovery.ServerFoundCallback += OnServerFound; } private void OnStartPlaying() { statusText.text = "Starting host..."; StartCoroutine(HostAndSearchRoutine()); } private void OnJoinMultiplayer() { statusText.text = "Searching for servers..."; ClearServerList(); foundServers.Clear(); networkDiscovery.StartSearchingForServers(); } private void OnServerFound(IPEndPoint endPoint) { if (foundServers.Contains(endPoint)) return; foundServers.Add(endPoint); // Auto-join if started as host if (InstanceFinder.IsServer) { //networkDiscovery.StopAdvertisingServer(); networkDiscovery.StopSearchingForServers(); uiCamera.enabled = false; InstanceFinder.ClientManager.StartConnection("192.168.42.212"); statusText.text = $"Joined server: {endPoint.Address}"; return; } // Display in UI for manual joining GameObject item = Instantiate(serverListItemPrefab, serverListContainer); TMP_Text label = item.GetComponentInChildren<TMP_Text>(); label.text = endPoint.Address.ToString(); Button btn = item.GetComponent<Button>(); btn.onClick.AddListener(() => { networkDiscovery.StopSearchingForServers(); if (uiCamera != null) uiCamera.enabled = false; InstanceFinder.ClientManager.StartConnection(endPoint.Address.ToString()); statusText.text = $"Joined server: {endPoint.Address}"; }); } private Coroutine joinRoutine; private IEnumerator HostAndSearchRoutine() { // Step 1: Start hosting InstanceFinder.ServerManager.StartConnection(); // Step 2: Start advertising yield return new WaitForSeconds(0.5f); // Let the server settle networkDiscovery.StartAdvertisingServer(); // Step 3: Begin searching yield return new WaitForSeconds(0.5f); // Let advertisement initialize networkDiscovery.StartSearchingForServers(); // Step 4: Try to find and join a better server yield return new WaitForSeconds(0.5f); // Give discovery a moment StartJoinRoutine(); } public void StartJoinRoutine() { if (joinRoutine != null) StopCoroutine(joinRoutine); joinRoutine = StartCoroutine(TryJoinServerRepeatedly()); } private IEnumerator TryJoinServerRepeatedly() { float timeout = 10f; float timer = 0f; while (timer < timeout) { if (foundServers.Count > 0) { var firstServer = foundServers[0]; //networkDiscovery.StopAdvertisingServer(); networkDiscovery.StopSearchingForServers(); InstanceFinder.ClientManager.StartConnection(firstServer.Address.ToString()); statusText.text = $"Joined server: {firstServer.Address}"; yield break; } statusText.text = $"Searching for servers... ({Mathf.FloorToInt(timer)}s)"; yield return new WaitForSeconds(1f); timer += 1f; } statusText.text = "No servers found. Acting as host."; // You can optionally start your own server here } private void ClearServerList() { foreach (Transform child in serverListContainer) { Destroy(child.gameObject); } } }