using ProjectM.Simulation; using Unity.Entities; using Unity.NetCode; using UnityEngine; namespace ProjectM.Client { /// /// Minimal IMGUI Host / Join (+ IP) panel for the M4 LAN flow — the connection entry point for player /// builds, where there is no editor auto-host. Writes a request into the /// relevant netcode world(s): Host makes the server world listen and the local client join over /// loopback; Join makes the client world connect to the typed IP. Hides itself once the client /// world has a connection. Direct IP/LAN only — Unity Relay is deferred to a later pass. In the editor /// the EditorAutoHostSystem usually connects first, so this panel just shows "Connected". /// public class ConnectionUI : MonoBehaviour { [SerializeField] ushort _port = 7979; string _ipField = "127.0.0.1"; void OnGUI() { if (IsClientConnected()) { GUILayout.BeginArea(new Rect(10, 10, 220, 26)); GUILayout.Label("Net: Connected"); GUILayout.EndArea(); return; } GUILayout.BeginArea(new Rect(10, 10, 240, 150), GUI.skin.box); GUILayout.Label("Project M — LAN co-op"); // Host is only possible where a server world exists (editor or a ClientServer/host build). if (ClientServerBootstrap.ServerWorld is { IsCreated: true }) { if (GUILayout.Button("Host")) { Seed(ClientServerBootstrap.ServerWorld, ConnectionMode.Host, "0.0.0.0", _port); Seed(ClientServerBootstrap.ClientWorld, ConnectionMode.Join, "127.0.0.1", _port); } GUILayout.Space(6); } GUILayout.Label("Join host IP:"); _ipField = GUILayout.TextField(_ipField); if (GUILayout.Button("Join")) Seed(ClientServerBootstrap.ClientWorld, ConnectionMode.Join, _ipField, _port); GUILayout.EndArea(); } static bool IsClientConnected() { var world = ClientServerBootstrap.ClientWorld; if (world is not { IsCreated: true }) return false; using var q = world.EntityManager.CreateEntityQuery(ComponentType.ReadOnly()); return !q.IsEmpty; } static void Seed(World world, ConnectionMode mode, string address, ushort port) { if (world is not { IsCreated: true }) return; var em = world.EntityManager; using var q = em.CreateEntityQuery(ComponentType.ReadWrite()); Entity e = q.IsEmpty ? em.CreateEntity(typeof(ConnectionConfig)) : q.GetSingletonEntity(); em.SetComponentData(e, new ConnectionConfig { Mode = mode, Address = address, Port = port, Requested = true, }); } } }