Unity editor doesn't connect to another instance over LAN

I am having more trouble with networking, I am still pretty new to networking. I have two computers, both running the same project in the unity editor. I am using git to sync them. When I try to host on one computer and join on the other, the client doesn’t connect. The IP and Port are correct, and I made sure to let unity.exe through the firewall on both PCs. The client is running on windows 10, and the host is running windows 11. If I build the project, it works fine but not in the editor. I need it to work in the editor to test it because I don’t have a PC powerful enough to run multiple instances. Does anyone know why the editor can’t connect to the server?

Did you set the serverListenAddress to “0.0.0.0”?

If it’s not specified in code (third parameter) or in the NetworkManager Inspector it’s set to “127.0.0.1” or the “allow remote connections” checkbox isn’t checked it will only allow local connections.

Also your two computers need to be in the same subnet ie connected through the same router/switch. If one machine were to use a 10.x.x.x IP and the other has a 192.168.x.x IP they can’t connect without setting up port forwarding on the routing device.

serverListenAddress is set to 0.0.0.0 and allow remote connections is checked in the inspector. Both computers are connected through the same router, and both of the IPs start with 10.x.x.x. I know it’s not an issue with the router because if I build the game, it works fine. Like I said before I made sure to let unity.exe through the firewall on both PCs, so I don’t think that is the problem. Is there anything else that could be stopping it from working? there is no information in my console that helps, just [Netcode] StartClient
[Netcode] initialize
[Netcode] Shutdown
It doesn’t give me any helpful information about what is going on. There is nothing in the console of the host, except for the usual StartHost and Initialize messages.

First: can you ping the other system’s IP?

Without seeing any of the code it’s really hard to tell what might be going on.
Then double-check that you are connecting the client to the host’s IP. You may want to use a network/packet sniffer to observe what’s going out and what’s coming in on both machines.

It could still be an incorrectly set up port forward, ie where it leads back to the client machine or the forwarding is for TCP rather than UDP.

I can ping the the computer running the host in windows command prompt just fine. I am not using port forwarding at all because the computers are both on the same network. Like I said before, it works in the build but not in the editor. Here is my code that handles connections:

using System.Collections;
using UnityEngine;
using Unity.Netcode.Transports.UTP;
using UnityEngine.UI;
using Unity.Netcode;
using System;
using System.Net;

public class MultiplayerJoinUI : MonoBehaviour
{
    // variables for the UI
    [SerializeField] private Button ServerBtn;
    [SerializeField] private Button ClientBtn;
    [SerializeField] private Button HostBtn;
    [SerializeField] private Button StartHostBtn;
    [SerializeField] private InputField ClientImp;
    [SerializeField] private TMPro.TMP_InputField HostImp;
    [SerializeField] private GameObject ConnectingBox;
    [SerializeField] private GameObject HostingBox;
    [SerializeField] private int connectionTries = 500;

    // backend variables
    Transform Hotbar;
    bool x = false;
    string addressIP = "";
    string addressPort = "";

    public void Hostbox()
    {
        x = !x;
        HostingBox.SetActive(x);
    }
    private void Awake()
    {
        // disable the hotbar before the first frame is rendered
        Hotbar = GameObject.Find("UI/Hotbar").transform;
        Hotbar.gameObject.SetActive(false);

        // called when the Host button is pressed
        StartHostBtn.onClick.AddListener(() =>
        {
            Hostbox();
        });
        // called when the server button is pressed
        ServerBtn.onClick.AddListener(() =>
        {
            NetworkManager.Singleton.StartServer();
            gameObject.SetActive(false);
        });

        // called when the client button is clicked
        ClientBtn.onClick.AddListener(() =>
        {
            bool ipDone = false;
            addressIP = string.Empty;
            addressPort = string.Empty;
            // loop through the client input to seperate the ip from the port
            foreach(char c in ClientImp.text)
            {
                if(ipDone == false)
                {
                    if(c != ':')
                    {
                        addressIP += c.ToString();
                    } else
                    {
                        ipDone = true;
                    }
                } else
                {
                    if (c != ':')
                    {
                        addressPort += c.ToString();
                    }
                }
            }
            Debug.Log("connecting... IP: " + addressIP + " PORT: " + addressPort);
            // convert Port string to int
            int P;
            int.TryParse(addressPort, out P);
            // fill in the port and IP on the networkManager
            NetworkManager.Singleton.GetComponent<UnityTransport>().ConnectionData.Address = addressIP;
            NetworkManager.Singleton.GetComponent<UnityTransport>().ConnectionData.Port = Convert.ToUInt16(P);
            // show the connecting message
            ConnectingBox.gameObject.SetActive(true);
            // start client connection
            NetworkManager.Singleton.StartClient();
            StartCoroutine(WaitForConnection());
        });
        // called when the client button is presed
        HostBtn.onClick.AddListener(() =>
        {
            addressPort = HostImp.text;
            string localIP = GetLocalIPAddress();
            int P;
            int.TryParse(addressPort, out P);
            // Added to try to debug this problem, this is not causing it.
            if (Application.isEditor) {
                NetworkManager.Singleton.GetComponent<UnityTransport>().ConnectionData.Address = localIP;
            }
            NetworkManager.Singleton.GetComponent<UnityTransport>().ConnectionData.Port = Convert.ToUInt16(P);
            NetworkManager.Singleton.StartHost();
            Debug.Log("Hosting on port " + addressPort);
            // Hide and show UI
            Hostbox();
            GameUIShow();
            gameObject.SetActive(false);
        });
    }

    void GameUIShow ()
    {
        Hotbar.gameObject.SetActive(true);
    }

    // show the connecting popup until connected.
    IEnumerator WaitForConnection()
    {
        int i = connectionTries;
        while (i > 0) 
        { 
            if (NetworkManager.Singleton.IsConnectedClient == true)
            {
                ConnectingBox.SetActive(false);
                GameUIShow();
                i = 0;
                gameObject.SetActive(false);
            }
            i -= 1;
            yield return new WaitForSeconds(0.01f);
        }
        if (NetworkManager.Singleton.IsConnectedClient == false)
        {
            NetworkManager.Singleton.Shutdown();
        }
        ConnectingBox.SetActive(false);
    }

    private string GetLocalIPAddress()
    {
        string localIP = "";
        try
        {
            var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
            foreach (var ip in host.AddressList)
            {
                if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) // IPv4
                {
                    localIP = ip.ToString();
                    break; // Found IPv4, exit loop
                }
            }
        }
        catch (Exception ex)
        {
            Debug.LogError("Error getting local IP: " + ex.Message);
            localIP = "127.0.0.1"; // Fallback to loopback (for single machine testing only)
        }

        return localIP;
    }
}

I know some of the code is probably not written the best it could be (WaitForConnection), but other than that, I don’t see anything that could be causing this problem.

I can’t notice anything that could cause the issue. I would suggest trying the netcode setup in an empty project, and use the NetworkManager Inspector Start buttons to try and make a connection. If this won’t work, it’s more likely a network issue. If it does work, it could be the code you’ve written.

In that case you should check that the ConnectionData itself is, just a quick look via the debugger to ensure it’s all correct. Because all the parsing and conversion make me suspicious.

Most, actually. :wink:

A few things worth noting:

  • GameObject.Find(“…”)
  • mixing UI code with what the UI code actually does (start network and such) (I know but even for testing you should separate that because it just takes more time to sift through combined UI + logic code)
  • calling StartXxx() without actually disabling the buttons, this would allow you to click it multiple times (ie accidental double click) possibly leading to issues
  • foreach over the IP string when you could simply use string.Split(“:”)
  • repeating the same code in multiple event listeners
  • action-based event listeners cannot be unsubscribed, and the code they contain cannot be called from elsewhere (thus the repetitions). Also I always find it super awkward to find UI code that runs at any time to be inlined in the Awake method.
  • WaitForConnection makes no sense. You have event callbacks ie OnClientDisconnected and such. Add my NetworkEventLogger to NetworkManager so you see when these events fire, in what order.
  • GetLocalIPAddress looks like the cheap and dirty solution that’s guaranteed to fail on many systems, specifically when you have two or more LAN network ports (many motherboards do)

I got it figured out. There was a random firewall rule blocking unity. I have no idea where it came from. Maybe it got added when I tried to allow unity through the firewall, but I don’t know why that would happen because I just used the “Allow an app through firewall” button on the windows firewall. Thanks for the feedback on the code though. I will make sure to fix that.