NAT Traversal - Automatic port forwarding, punch-through, and more!

Adds NAT punch-through and automatic port forwarding to any peer-to-peer networking API

Reduces latency and saves you money by connecting players directly whenever possible, even behind a router.

You only need three methods: StartHostAll(), listMatches(), and StartClientAll() to connect.

Falls back to Unity’s relay servers only if punch-through fails, so players can always connect.

Works on Windows, Linux, and OSX

Asset | Docs | API | FAQ | Demo

Direct connect whenever possible
Why waste your hard earned money using bandwidth on the relay servers if you don’t have to? A direct connection means less lag and less dependence on infrastructure that you don’t control.

Seamless connection replacing
Your players will always use the best connection possible, seamlessly switching from relay to direct connections as they become available.

Faster connection
Gets your players in the game faster by not waiting for a UNET match to be created or joined before connecting.

Set client connect port
Includes the ability to set the port that clients connect from. Just in case you need that.

Note: Punch-through requires an externally hosted server to run the included Facilitator on.

Note: Web builds are not supported. Unfortunately the library we use (RakNet) does not work with WebSockets. Sorry!

Demo video

Tutorial

But Why?
The primary motivation for creating this was so that I could be less dependent on Unity’s relay servers. For one, they are bandwidth restricted, and they seem to introduce some pretty high latency. Plus it’s just one more point of failure that us lowly developers have absolutely no control over. This solution should mean that connecting through Unity’s relay servers is almost never necessary.

Requirements
Unity 5.2 or above. Tested in 5.2.0f2, 5.3.0f4, 5.3.4f1, 5.3.5f1, 5.4.0b3, 5.4.0b15, 5.4.0b22, 5.4.1f1, 5.5.0f3, 5.6.0b11, 5.6.2f1, 2017.1.0f3

The Facilitator
There are two versions of the Facilitator packaged with the plugin. One for windows and one for linux. You can also always get the latest versions below:

If you have any questions just let me know. I hang around in the forums all the time. I’m also always available at the support email. I’m actively developing this plugin for use in my own game so I respond to issues / put out fixes quickly.

Thanks!

Also check out our other plugin to smoothly sync transforms and rigidbodies over the network: Smooth Sync

5 Likes

Can I use with this asset?

UNET ‘Server + MySQL and Clients’

and do you plan an integration with the PlayMaker or ICode?

I haven’t tested with UNET ‘Server + MySQL and Clients’ but by reading the description it seems like it should work. I’m using mysql right now in my own project to store the matchID and raknet guid so there’s definitely no problem integrating with mysql.

I hadn’t considered integration with PlayMaker or ICode but it’s something I can look into.

1 Like

Version 1.2 has been released into the wild!

Changes include:

  • Simplified interface: I made a couple more parameters optional in the StartHostAll() and StartClientAll() methods so that it is even easier to set up.
  • Cleaned up some logging: Because who doesn’t like helpful error messages
  • Fixed an issue with disconnecting and reconnecting: This was a legit bug that would occur if a client disconnected from the host and the reconnected to the same host. Now fixed.
  • Made some harmless error messages go away: Unity was throwing a couple of harmless errors because of some functionality that I overrode / extended. I made the errors go away.
  • Fixed an error that could be thrown if the game is stopped immediately after running: Yep.

I’ve heard back from a couple of people who have tried the asset and reported that the punch-through is properly punching and letting them connect through routers no problem. It’s really great hearing the sense of relief from happy devs finally able to get their players directly connected :slight_smile:

1 Like

This is fantastic, it could be the thing that I was looking for.

A noob question, with this NAT punch through can I do a game for PS4 using the PS4 network without the CCU charge or the PS4 network use other kind of port forward?

I’m afraid I’m just not knowledgeable enough to answer your question very well, but I think the way it works is that sony provides their own nat-punchthrough / port forwarding / relay infrastructure so you don’t have to use Unity’s anyway. And I think it’s probably free. I’m really guessing here though so don’t take my word on it. I’m mostly going off of how steam works and what little I know of how xbox works.

Of course the advantage of sticking with the UNET infrastructure (with my plugin) is that you could (ideally) use the exact same infrastructure / network code on all platforms, unfortunately I’m not really sure if this is something sony or microsoft will allow. They may force you to use their own infrastructure, or at the very least they will make you jump through some hoops to be able to host your own Facilitators.

My studio is working on getting our own game out on the consoles as well so I’ll have some more concrete answers in the future when we start working on the console ports, but as of right now I don’t think I would recommend using this plugin if the only platform you are releasing on is ps4.

Thanks for the fast, honest and detailed answer!. In any case I’ll buy the assets in order to test my moba for pc, thanks again!

1 Like

Is there an option to define which relay server is used? As in case you didn’t know, players from different relay servers can’t connect with each other. There are currently three different matchmaking/relay servers located in US, Europe and Asia. It would be required to manually set the relay server, if the match comes from any external matchmaking source (like Steam server listing etc.)

Yeah, it works exactly like the normal NetworkManager provided by unity. You can either set the matchHost in the inspector or from a script.

Hello!

You are not 100% on how well this will work with OSX. Could you add some more details about Mac/OSX support, since that is a platform which we are supporting?

Thanks!
Jos

@Jos-Yule Sorry for the delayed response. OSX support is something I was actively working on so I didn’t want to say one way or the other until I figured it out.

I am very happy to announce that OSX is now fully supported. I’m packaging the update right now. It will be available on the asset store in 5-10 days.

I will make sure to update all of the documentation accordingly.

Version 1.3 is now live. This a pretty big update, including some new videos to help you get started using the plugin.

Changes include:

  • Added support for OSX
  • Fixed hostInternalIP and hostExternalIP not being set on the host
  • Added the option to disable unity matchmaking so that it can be replaced with other matchmaking systems such as steam lobbies.
  • New demo video
  • New tutorial video
  • Updated documentation

Check out the new videos below:

Demo

Tutorial

Well, this looks handy, maybe a video explaining some of the magic? because this looks kind of “too good to be true” (?)

1 Like

@metalkat I assure you it’s not magic, though I’m flattered that you think so :slight_smile:

Maybe it will help ease your mind a bit to know that the plugin is built on two very solid and proven technologies. The automatic port forwarding is provided by Open.NAT and the punch-through is done using RakNet, which is actually the library that Unity’s own networking was based on before the switch to UNet.

You may remember the Facilitator from the pre-UNet days. That was how people got connected before the relay servers were a thing. My plugin basically brings back that functionality to UNet.

1 Like

@thegreatzebadiah Great news about OSX support. Just bought it, got the Facilitator running @ EC2, demo scene working great. Would like an example or hint of how to remove the Unity Matchmaker - we are currently using the Steam Matchmaking API, but just a generic “how to swap for Unity Matchmaker for generic replacement” pointer would be be great.

Thanks for the excellent update,
Jos

Further - my ideal setup is to use Steam’s matchmaking, but still have access to Unity’s relay service, for the cases where Upnp & Punch-Through fail. :slight_smile:

Hurm, i also see that this is a NetworkManager replacement - i’m making use of the NetworkLobbyManager, and particularly the lobby join/switch callbacks, to pass data from the lobby player to the network player… Have to figure out how to replicate that functionality.

@Jos-Yule

The steam stuff should be super easy. All you need to do is uncheck Use Unity Matchmaking and instead use a steam lobby to pass around the host’s connection info.

After you call StartHostAll() when you receive the callback to OnMatchCreate() you should create a steam lobby and add the host’s connection info as lobby data.

SteamMatchmaking.SetLobbyData(steamIDLobby, “matchID”, createMatchResponse.networkId);
SteamMatchmaking.SetLobbyData(steamIDLobby, “guid”, NATHelper.guid.ToString());
SteamMatchmaking.SetLobbyData(steamIDLobby, “publicIP”, externalIP);
SteamMatchmaking.SetLobbyData(steamIDLobby, “internalIP”, internalIP);

Clients can then find and join the steam lobby using the steamworks api as normal. Once they are in a lobby they read the host’s connection info from the lobby data and pass it to StartClientAll().

The relay servers are still used as a fallback (as long as you don’t uncheck Connect Relay) so it should do exactly what you want.

As for the NetworkLobbyManager…I’m not so sure. I’ve never used it myself so I’ll have to look into it a bit and see if I can get it working with the plugin. That being said, the NetworkManager provided by the plugin extends from Unity’s built-in NetworkManager so it’s probably not that far off.

Thanks for the pointers to using the Unity Matchmaker with the steam stuff - that is way easier then i thought it would be!

WRT the lobby, the idea is that there is a “lobby” player prefab, and a lobby scene, which is NOT the game itself, where you can set up all your pre-game stuff, and then move to the game scene, which is when the network player prefab is created. You then get a callback with the lobby player prefab and the network player prefab (instances), so you can copy/update the data/setup from the lobby into the “real” player. The only thing we are doing in the lobby is setting up the controller stuff the player is using, so we could probably drop using it, honestly…

The NetworkLobbyManager seems like something I can get working, but I can’t say how soon. I’m packaging up the next update right now so it won’t make it into this one at least.

In the meantime maybe you can try copying and modifying the code for NetworkLobbyManager.
Create a new script (AdvancedNetworkLobbyManager maybe), paste in the code, and where it extends from NetworkManager change it to extend from NATTraversal.NetworkManager instead.
Then wherever you are using the NetworkLobbyManager instead use the new AdvancedNetworkLobbyManager script you just created. That should at least give you access to the functionality provided by the plugin, but I have no idea if it will play nice with everything else in the lobby manager.

If by some miracle that works flawlessly please do let me know. I always love to get good news :slight_smile: