Il s'agit de monorepository UnityEngine de Heroic Labs qui contient des bibliothèques pour accéder à deux services backend différents, Nakama et Satori.
Les clients sont construits sur le client .NET avec des extensions pour Unity Engine. Ils nécessitent que la version d'exécution de Scripting .NET 4.6 soit définie dans l'éditeur.
Nakama est un serveur open source conçu pour alimenter les jeux et les applications modernes. Les fonctionnalités incluent les comptes d'utilisateurs, le chat, le social, le matchmaker, le multijoueur en temps réel et bien plus encore.
La documentation complète est en ligne - https://heroiclabs.com/docs/unity-lient-guide
Vous devrez configurer le serveur et la base de données avant de pouvoir vous connecter avec le client. Le moyen le plus simple consiste à utiliser Docker mais jetez un œil à la documentation du serveur pour d'autres options.
Installez et exécutez les serveurs. Suivez ces instructions.
Installez le SDK Unity. Vous avez trois options pour cela.
Pour utiliser une version officielle, vous pouvez télécharger le .UnityPackage ou .Tar à partir de la page des versions et l'importer dans votre projet. Si vous choisissez l'option .tar, vous pouvez l'importer à partir d'une liste déroulante dans la fenêtre Unity Package Manager.
Alternativement, si vous souhaitez vérifier une version spécifique ou vous engager à partir de GitHub et utiliser Unity 2019.4.1 ou version ultérieure, vous pouvez ajouter ce qui suit au fichier manifest.json dans le dossier Packages de votre projet:
"com.heroiclabs.nakama-unity" : " https://github.com/heroiclabs/nakama-unity.git?path=/Packages/Nakama#<commit | tag> "Votre dernière option consiste à télécharger des binaires préconçus de la boutique d'actifs.
Utilisez les informations d'identification de connexion pour créer un objet client.
using Nakama ;
const string scheme = "http" ;
const string host = "127.0.0.1" ;
const int port = 7350 ;
const string serverKey = "defaultkey" ;
var client = new Client ( scheme , host , port , serverKey , UnityWebRequestAdapter . Instance ) ; L'objet client dispose de nombreuses méthodes pour exécuter diverses fonctionnalités du serveur ou ouvrir des connexions de socket en temps réel avec le serveur.
Il existe une variété de façons de s'authentifier avec le serveur. L'authentification peut créer un utilisateur s'il n'existe pas déjà avec ces informations d'identification. Il est également facile d'authentifier avec un profil social de Google Play Games, Facebook, Game Center, etc.
var deviceId = SystemInfo . deviceUniqueIdentifier ;
var session = await client . AuthenticateDeviceAsync ( deviceId ) ;
Debug . Log ( session ) ; Lorsqu'il est authentifié, le serveur répond avec un token Auth (JWT) qui contient des propriétés utiles et est désérialisé en un objet Session .
Debug . Log ( session . AuthToken ) ; // raw JWT token
Debug . LogFormat ( "Session user id: '{0}'" , session . UserId ) ;
Debug . LogFormat ( "Session user username: '{0}'" , session . Username ) ;
Debug . LogFormat ( "Session has expired: {0}" , session . IsExpired ) ;
Debug . LogFormat ( "Session expires at: {0}" , session . ExpireTime ) ; // in seconds.Il est recommandé de stocker le jeton AUTH à partir de la session et de vérifier au démarrage s'il a expiré. Si le jeton a expiré, vous devez vous réautoriser. Le temps d'expiration du jeton peut être modifié en tant que paramètre dans le serveur.
const string prefKeyName = "nakama.session" ;
ISession session ;
var authToken = PlayerPrefs . GetString ( prefKeyName ) ;
if ( string . IsNullOrEmpty ( authToken ) || ( session = Session . Restore ( authToken ) ) . IsExpired )
{
Debug . Log ( "Session has expired. Must reauthenticate!" ) ;
} ;
Debug . Log ( session ) ;Le client comprend de nombreuses API intégrées pour diverses fonctionnalités du serveur de jeux. Ceux-ci sont accessibles avec les méthodes asynchrones. Il peut également appeler la logique personnalisée sous forme de fonctions RPC sur le serveur. Ceux-ci peuvent également être exécutés avec un objet Socket.
Toutes les demandes sont envoyées avec un objet de session qui autorise le client.
var account = await client . GetAccountAsync ( session ) ;
Debug . LogFormat ( "User id: '{0}'" , account . User . Id ) ;
Debug . LogFormat ( "User username: '{0}'" , account . User . Username ) ;
Debug . LogFormat ( "Account virtual wallet: '{0}'" , account . Wallet ) ;Les demandes peuvent être fournies avec des configurations de nouvelle tentative en cas d'erreurs de réseau ou de serveur transitoires.
Une seule configuration peut être utilisée pour contrôler tous les comportements de réessayer de la demande:
var retryConfiguration = new RetryConfiguration ( baseDelay : 1 , maxRetries : 5 , delegate { System . Console . Writeline ( "about to retry." ) ; } ) ;
client . GlobalRetryConfiguration = retryConfiguration ;
var account = await client . GetAccountAsync ( session ) ;Ou, la configuration peut être fournie sur une base par demande:
var retryConfiguration = new RetryConfiguration ( baseDelay : 1 , maxRetries : 5 , delegate { System . Console . Writeline ( "about to retry." ) ; } ) ;
var account = await client . GetAccountAsync ( session , retryConfiguration ) ;Les configurations de réchauffement par répétition remplacent la configuration globale de réchauffement.
Les demandes peuvent également être fournies avec un jeton d'annulation si vous avez besoin de les annuler à mi-vol:
var canceller = new CancellationTokenSource ( ) ;
var account = await client . GetAccountAsync ( session , retryConfiguration : null , canceller ) ;
await Task . Delay ( 25 ) ;
canceller . Cancel ( ) ; // will raise a TaskCanceledExceptionLe client peut créer une ou plusieurs sockets avec le serveur. Chaque prise peut faire enregistrer ses propres écouteurs d'événements pour les réponses reçues du serveur.
var socket = client . NewSocket ( ) ;
socket . Connected += ( ) => Debug . Log ( "Socket connected." ) ;
socket . Closed += ( ) => Debug . Log ( "Socket closed." ) ;
await socket . ConnectAsync ( session ) ; Si vous souhaitez que les gestionnaires de socket exécutent l'extérieur du thread principal d'Unity, passez le useMainThread: false argument:
var socket = client . NewSocket ( useMainThread : false ) ; Vous pouvez capturer des erreurs lorsque vous utilisez un échafaudage await avec des tâches en C #.
try
{
var account = await client . GetAccountAsync ( session ) ;
Debug . LogFormat ( "User id: '{0}'" , account . User . Id ) ;
}
catch ( ApiResponseException e )
{
Debug . LogFormat ( "{0}" , e ) ;
} Vous pouvez éviter l'utilisation de await où les exceptions devront être capturées et utiliser Task.ContinueWith(...) comme style de rappel avec C # standard si vous préférez.
client . GetAccountAsync ( session ) . ContinueWith ( t =>
{
if ( t . IsFaulted || t . IsCanceled )
{
Debug . LogFormat ( "{0}" , t . Exception ) ;
return ;
}
var account = t . Result ;
Debug . LogFormat ( "User id: '{0}'" , account . User . Id ) ;
} ) ;Satori est un serveur LIVEOPS pour les jeux qui alimente l'analyse exploitable, les tests A / B et la configuration distante. Utilisez le client Satori Unity pour coomuniquer avec Satori à partir de votre jeu Unity.
La documentation complète est en ligne - https://heroicLabs.com/docs/satori/client-libraires/unity
Créez un objet client qui accepte l'API qui vous a été donné en tant que client Satori.
using Satori ;
const string scheme = "https" ;
const string host = "127.0.0.1" ; // add your host here
const int port = 443 ;
const string apiKey = "apiKey" ; // add the api key that was given to you as a Satori customer.
var client = new Client ( scheme , host , port , apiKey ) ;Authentifiez ensuite avec le serveur pour obtenir votre session.
// Authenticate with the Satori server.
try
{
session = await client . AuthenticateAsync ( id ) ;
Debug . Log ( "Authenticated successfully." ) ;
}
catch ( ApiResponseException ex )
{
Debug . LogFormat ( "Error authenticating: {0}" , ex . Message ) ;
}En utilisant le client, vous pouvez obtenir des expériences ou des indicateurs de fonctionnalité, l'utilisateur appartient.
var experiments = await client . GetExperimentsAsync ( session ) ;
var flag = await client . GetFlagAsync ( session , "FlagName" ) ;Vous pouvez également envoyer des événements arbitraires au serveur:
await client . EventAsync ( session , new Event ( "gameLaunched" , DateTime . UtcNow ) ) ;Il s'agit seulement d'un sous-ensemble de l'API client Satori, veuillez donc consulter le lien de documentation répertorié précédemment pour l'API complète.
Pour les versions de Nakama et Satori Webgl, vous devez vous assurer que l' IHttpAdapter transmis dans le client est un UnityWebRequestAdapter .
var client = new Client ( "defaultkey" , UnityWebRequestAdapter . Instance ) ; Pour Nakama, utilisez la méthode d'extension NewSocket() pour créer la prise ou définir manuellement le bon ISocketAdapter par plate-forme.
var socket = client . NewSocket ( ) ;
// or
#if UNITY_WEBGL && ! UNITY_EDITOR
ISocketAdapter adapter = new JsWebSocketAdapter ( ) ;
#else
ISocketAdapter adapter = new WebSocketAdapter ( ) ;
#endif
var socket = Socket . From ( client , adapter ) ;Lorsque vous testez notre exemple de scène Webgl avant 2021.1, assurez-vous d'entrer dans les paramètres de build et de définir la configuration du compilateur C ++ à publier au lieu de déboguer en raison d'un problème exceptionnel dans Unity WebGl builds: https://issuetracker.unity3d.com/issues/webgl-build-throws-threads-are-not-reabled-for-this-platform-error-when-progs-built-using-debug-c-plaflur-compiler-configuration
La feuille de route de développement est gérée car les problèmes de github et les demandes de traction sont les bienvenus. Si vous souhaitez améliorer le code, veuillez ouvrir un problème pour discuter des modifications ou passer et en discuter dans le forum communautaire.
Ce projet peut être ouvert dans Unity pour créer un ".UnityPackage".
Ce projet est concédé sous licence Apache-2.