Basic Networking

Short version: I can’t establish a connection between clients.

Longer version: Below, I’m trying to implement a very simple direct connect multiplayer functionality without need of a master server. My direction is similar to the games Minecraft and The Forest. I am currently using a router (D-Link 615). I have port forwarded. I keep getting NAT target 0 not connected to NAT facilitator 67.225.180.24:50005 when I do RefreshIP. Also NAT target 24 errors when I use Join Game and type in my IP. I’m not sure if I need to do some firewall tinkering (and what part I need to do), or I’m just missing a simple step.

I have read up on networking with the main unity website and several tutorials (however they do not explain how to create a direct connect system or handle the error’s I’m getting), so please do not give me links that explain how basic networking works. The only thing I could use clarifying on is NAT punchthrough as the Unity documentation isn’t as clear for me to understand.

I’ve read several sources where it says master servers are not required.
here and here.

I’m familiar with Photon Unity Networking, however, that limits how often the players can interact with each other unless I pay for more. My level of multiplayer should be doable by Unity without needing Photon.

using UnityEngine;
using System.Collections;

public class startScreen : MonoBehaviour {

	float screenWidth;
	float screenHeight;
	string ipAddress;
	string port;

	string myIP;
	int myPort;

	string networkStatus;

	bool gameStarted = false;

	public Object fpc; //first person controller

	// Use this for initialization
	void Start () {
		screenWidth = Screen.width-(Screen.width*.1f);
		screenHeight = Screen.height-(Screen.height*.1f);
		ipAddress = "";
		port = "";
		networkStatus = "";
	}
	
	// Update is called once per frame
	void Update () {

	}

	void OnGUI () {
		if(!gameStarted){
			GUI.BeginGroup(new Rect(Screen.width/2-(Screen.width*.9f/2), Screen.height/2-(Screen.height*.9f/2),
			                        Screen.width-(Screen.width*.1f), Screen.height-(Screen.height*.1f)));
			GUI.Box(new Rect(0,0,Screen.width-(Screen.width*.1f),Screen.height-(Screen.height*.1f)),"Welcome to the game!");

			if(GUI.Button(new Rect(10,30,100,20), "Refresh IP")){
				getMyIP();
			}

			//Host IP and Port
			GUI.Label(new Rect(120,30,20,20),"IP: ");
			GUI.Label(new Rect(140,30,120,20),myIP);
			GUI.Label(new Rect(270,30,40,20),"Port:");
			GUI.Label(new Rect(310,30,80,20),myPort.ToString());

			int shift1 = 20;
			if(GUI.Button(new Rect(10,30+shift1,100,20), "Host Game")){
				HostGame();
			}

			if(GUI.Button(new Rect(10,54+shift1,100,20), "Join Game")){
				JoinGame();
			}

			//input fields to join a game
			GUI.Label(new Rect(120,54+shift1,20,20),"IP:");
			ipAddress = GUI.TextField(new Rect(140,54+shift1,120,20), ipAddress);
			GUI.Label(new Rect(270,54+shift1,40,20),"Port:");
			port = GUI.TextField(new Rect(310,54+shift1,80,20), port);

			if(GUI.Button(new Rect(10,78+shift1,100,20), "Start Game")){
				StartGame();
			}

			GUI.Label(new Rect(10,100+shift1,Screen.width-(Screen.width*.1f)-20,100),networkStatus);
			GUI.EndGroup();
		}
	}

	void StartGame(){ //activates all connected members to rpc call to start game
		gameStarted = true;
		Camera.main.GetComponent<Transform>().gameObject.SetActive(false);
		Network.Instantiate(fpc,new Vector3(5,2,5),Quaternion.identity,0);
	}

	void HostGame(){
		Network.InitializeServer(5,80,!Network.HavePublicAddress());
	}

	void JoinGame(){
		Network.Connect(ipAddress, port);
	}

	void getMyIP(){
		Network.Connect("http://www.google.com");
		myIP = Network.player.externalIP;
		myPort = Network.player.externalPort;

		Debug.Log(Network.player.externalIP);
		Debug.Log(Network.player.externalPort);
		Debug.Log(!Network.HavePublicAddress());
	}

	void OnConnectedToServer() {
		networkStatus = "Connected to Server";
	}

	void OnDisconnectedFromServer() {
		networkStatus = "Disconnected from Server";
	}

	void OnFailedToConnect() {
		networkStatus = "Failed to Connect";
	}

	void OnPlayerConnected(){
		networkStatus = "Player has connected";
	}

	void OnPlayerDisconnected(){
		networkStatus = "Player has disconnected";
	}

	void OnServerInitialized(){
		networkStatus = "Server Initialized";
	}
}

Heres a tutorial that might help: