A lightweight plugin to allow Unity games to use Netcode.IO for secure UDP socket communication.
C#
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

README.md

Unity-Netcode.IO

A lightweight and easy-to-use plugin to allow Unity games to take advantage of the Netcode.IO protocol for secure UDP communication.

Netcode.IO.NET

While a JSLIB wrapper is used to provide Netcode.IO in WebGL builds, Unity-Netcode.IO also makes use of Netcode.IO.NET to provide support on all other platforms. Because of this, all classes within the Netcode.IO.NET project are available in this project as well under the NetcodeIO.NET namespace.

Usage

All API functions are in the UnityNetcodeIO namespace. First, query for Netcode.IO support with UnityNetcode.QuerySupport:

// check for Netcode.IO extension
// Will provide NetcodeIOSupportStatus enum, either:
// Available, if Netcode.IO is available and the standalone helper is installed (or if in standalone),
// Unavailable, if Netcode.IO is unsupported (direct user to install extension)
// HelperNotInstalled, if Netcode.IO is available but the standalone helper is not installed (direct user to install the standalone helper)
UnityNetcode.QuerySupport( (supportStatus) =>
{
} );

Next, create a client using UnityNetcode.CreateClient:

// create a Netcode.IO client using the given protocol
// Protocol is either NetcodeIOClientProtocol.IPv4 or NetcodeIOClientProtocol.IPv6
UnityNetcode.CreateClient( protocol, (client)=>
{
} );

Assuming you have a byte[] connect token and a client created, you can connect to a server using NetcodeClient.Connect:

client.Connect( connectToken, () =>
{
	// client connected!
}, ( err ) =>
{
	// client failed to connect, err contains error message
} );

You can query the status of a client using NetcodeClient.QueryStatus:

client.QueryStatus( (status)=>
{
} );

You can add a listener for when packets are received using NetcodeClient.AddPayloadListener:

client.AddPayloadListener( (clientReceiver, packet) =>
{
	// clientReceiver is the client receiving the packet
	// packet contains client ID (as originally issued by token server) and ByteBuffer of packet payload
	// note that the payload will be returned to a pool after this handler runs, so do not keep a reference to it!
} );

You can send packets to the server using NetcodeClient.Send:

byte[] data;
// ...
client.Send( data );	// data must be between 1 and 1200 bytes

You can set a client's tickrate using NetcodeClient.SetTickrate:

client.SetTickrate( ticksPerSecond );

And finally, you can destroy a client using UnityNetcode.DestroyClient:

// disconnects and destroys the client. Note that the client cannot be reused after this!
UnityNetcode.DestroyClient( client );

Server API

The server API relies on some classes under the NetcodeIO.NET namespace, so be sure to include it with any code using the server API. Note that the Server API is not compatible with WebGL - attempting to create a server will throw a NotImplementedException. All other platforms may use it, however.

To create a new server, use:

var server = UnityNetcode.CreateServer(
	ip,		// string public IP clients will connect to
	port,		// port clients will connect to
	protocolID,	// ulong number used to identify this application. must be the same as the token server generating connect tokens.
	maxClients,	// maximum number of clients who can connect
	privateKey );	// byte[32] private encryption key shared between token server and game server

To listen to the server's events:

// Called when a client connects to the server
server.ClientConnectedEvent.AddListener( callback );	// void( RemoteClient client );

// Called when a client disconnects from the server
server.ClientDisconnectedEvent.AddListener( callback );	// void( RemoteClient client );

// Called when a client sends a payload to the server
// Note that byte[] payload will be returned to a pool after the callback, so don't keep a reference to it.
server.ClientMessageEvent.AddListener( callback );	// void( RemoteClient sender, ByteBuffer payload );

To start and stop the server, use:

server.StartServer();	// start listening for clients
server.StopServer();	// stop server and disconnect any clients

To send a payload to a client, use:

server.SendPayload( remoteClient, ByteBuffer payload );	// payload must be between 1 and 1200 bytes.

To disconnect a client, use:

server.Disconnect( remoteClient );

To dispose of a server, use:

server.Dispose();

ByteBuffer

Note that the client and server APIs both make use of a ByteBuffer class. This is a helper class which provides the functionality of a resizable byte array, with some extra helper methods on top. You may use a ByteBuffer as if it were an array - access bytes using buffer[index] and check its size using buffer.Length. Additionally, you can copy data from other byte arrays using buffer.BufferCopy( sourceArray, sourceIndex, destinationIndex, bytesToCopy ), or other ByteBuffers in another overload of the same function.

Additionally, you can use the BufferPool class to allocate and release buffers in a memory-friendly way:

// to retrieve a buffer from the pool...
var buffer = BufferPool.GetBuffer( numBytes );

// and to return a buffer to the pool.
BufferPool.ReturnBuffer( buffer );

Platforms

UnityNetcode.IO runs on all platforms which support raw socket communication, as well as WebGL with the use of a wrapper around this browser extension which brings Netcode.IO support to the browser.

Known Issues

  • In a browser, the callback passed for connect is always called immediately regardless of successful connection, the error callback is never called regardless of connection failures. I could set up a continuous asynchronous poll, though there's an update pending approval which adds the ability to directly listen for state changes with a callback to the underlying JS API, which would be a better solution. In the meantime it's still possible to set up a continuous poll and manually check for state changes.

A note about UDP and unreliability

UnityNetcode.IO is a Unity API for working with the Netcode.IO protocol. At its heart, Netcode.IO is an encryption and connection based abstraction on top of UDP. And, just like UDP, it has zero guarantees about reliability. Your messages may not make it, and they may not make it in order. That's just a fact of the internet. That said, any game will almost certainly need some kind of reliability layer. To that end, my ReliableNetcode.NET project provides an agnostic and easy to use reliability layer you can use to add this functionality to your game.