Este é o Monorepositório UnityEngine Heroic Labs que contém bibliotecas para acessar dois serviços de backend diferentes, Nakama e Satori.
Os clientes são construídos no cliente .NET com extensões para o Unity Engine. Eles exigem que a versão do tempo de execução do .NET 4.6 seja definida no editor.
Nakama é um servidor de código aberto projetado para alimentar jogos e aplicativos modernos. Os recursos incluem contas de usuário, bate -papo, social, casamenteiro, multiplayer em tempo real e muito mais.
A documentação completa está online-https://heroiclabs.com/docs/unity-cient-guide
Você precisará configurar o servidor e o banco de dados antes de se conectar com o cliente. A maneira mais simples é usar o Docker, mas dê uma olhada na documentação do servidor para outras opções.
Instale e execute os servidores. Siga estas instruções.
Instale o Unity SDK. Você tem três opções para isso.
Para usar um lançamento oficial, você pode baixar a página .UnityPackage ou .tar da página de lançamentos e importá -la para o seu projeto. Se você escolheu a opção .tar, poderá importá -la de um suspensão na janela do Unity Package Manager.
Como alternativa, se você quiser fazer o check -out de uma versão ou comprometimento específico do GitHub e estiver usando o Unity 2019.4.1 ou posterior, poderá adicionar o seguinte ao arquivo manifest.json na pasta Packages do seu projeto:
"com.heroiclabs.nakama-unity" : " https://github.com/heroiclabs/nakama-unity.git?path=/Packages/Nakama#<commit | tag> "Sua opção final é baixar binários pré -construídos na loja de ativos.
Use as credenciais de conexão para criar um objeto cliente.
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 ) ; O objeto cliente tem muitos métodos para executar vários recursos no servidor ou abrir conexões de soquete em tempo real com o servidor.
Há várias maneiras de autenticar com o servidor. A autenticação pode criar um usuário se ele ainda não existir com essas credenciais. Também é fácil de autenticar com um perfil social do Google Play Games, Facebook, Game Center etc.
var deviceId = SystemInfo . deviceUniqueIdentifier ;
var session = await client . AuthenticateDeviceAsync ( deviceId ) ;
Debug . Log ( session ) ; Quando autenticado, o servidor responde com um token de autenticação (JWT) que contém propriedades úteis e se destrializa em um objeto 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.Recomenda -se armazenar o token de autenticação a partir da sessão e verificar na inicialização, se expirou. Se o token expirou, você deve reautenticar. O tempo de validade do token pode ser alterado como uma configuração no servidor.
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 ) ;O cliente inclui muitas APIs embutidas para vários recursos do servidor de jogos. Estes podem ser acessados com os métodos assíncronos. Ele também pode chamar a lógica personalizada como funções RPC no servidor. Eles também podem ser executados com um objeto de soquete.
Todas as solicitações são enviadas com um objeto de sessão que autoriza o cliente.
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 ) ;As solicitações podem ser fornecidas com configurações de nova tentativa em casos de rede transitória ou erros de servidor.
Uma única configuração pode ser usada para controlar todo o comportamento da tentativa de solicitação:
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, a configuração pode ser fornecida por solicitação:
var retryConfiguration = new RetryConfiguration ( baseDelay : 1 , maxRetries : 5 , delegate { System . Console . Writeline ( "about to retry." ) ; } ) ;
var account = await client . GetAccountAsync ( session , retryConfiguration ) ;As configurações de tentativa de repetição de repetição substituem a configuração global de repetição.
As solicitações também podem ser fornecidas com um token de cancelamento se você precisar cancelá-los no meio do voo:
var canceller = new CancellationTokenSource ( ) ;
var account = await client . GetAccountAsync ( session , retryConfiguration : null , canceller ) ;
await Task . Delay ( 25 ) ;
canceller . Cancel ( ) ; // will raise a TaskCanceledExceptionO cliente pode criar um ou mais soquetes com o servidor. Cada soquete pode ter seus próprios ouvintes de evento registrados para obter respostas recebidas do servidor.
var socket = client . NewSocket ( ) ;
socket . Connected += ( ) => Debug . Log ( "Socket connected." ) ;
socket . Closed += ( ) => Debug . Log ( "Socket closed." ) ;
await socket . ConnectAsync ( session ) ; Se você deseja que os manipuladores de soquete executem o tópico principal da unidade, passe o useMainThread: false Argument:
var socket = client . NewSocket ( useMainThread : false ) ; Você pode capturar erros quando usar await Standing com tarefas em C#.
try
{
var account = await client . GetAccountAsync ( session ) ;
Debug . LogFormat ( "User id: '{0}'" , account . User . Id ) ;
}
catch ( ApiResponseException e )
{
Debug . LogFormat ( "{0}" , e ) ;
} Você pode evitar o uso de await onde as exceções precisarão ser capturadas e usar Task.ContinueWith(...) como um estilo de retorno de chamada com C# padrão, se preferir.
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 ) ;
} ) ;O Satori é um servidor LiveOps para jogos que alimentam análises acionáveis, teste A/B e configuração remota. Use o Satori Unity Client para coomunicar com o Satori do seu jogo de unidade.
A documentação completa está online - https://heroiclabs.com/docs/satori/client-libraries/unity
Crie um objeto cliente que aceite a API que você recebeu como cliente da 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 ) ;Em seguida, autentique -se com o servidor para obter sua sessão.
// 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 ) ;
}Usando o cliente em que você pode obter experimentos ou sinalizadores de recursos, o usuário pertence.
var experiments = await client . GetExperimentsAsync ( session ) ;
var flag = await client . GetFlagAsync ( session , "FlagName" ) ;Você também pode enviar eventos arbitrários para o servidor:
await client . EventAsync ( session , new Event ( "gameLaunched" , DateTime . UtcNow ) ) ;Este é apenas um subconjunto da API do cliente Satori; portanto, consulte o link de documentação listado anteriormente para a API completa.
Para as compilações Nakama e Satori WebGL, você deve garantir que o IHttpAdapter passado para o cliente seja um UnityWebRequestAdapter .
var client = new Client ( "defaultkey" , UnityWebRequestAdapter . Instance ) ; Para Nakama, use o método de extensão NewSocket() para criar o soquete ou definir manualmente o ISocketAdapter direito por plataforma.
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 ) ;Ao testar nosso exemplo de cena do WebGL antes de 2021.1, não deixe de entrar nas configurações de construção e definir a configuração do compilador C ++ para lançar em vez de depuração devido a um excelente problema no Unity WebGl Builds: https://issuetracker.unity3d.com/issues/webgl-build-throws-threads-are-not-enabled-for-this-platform-error-when-programas-built-useing-debug-c-plus-plus-plus-compiler-Configuration
O Roteiro de Desenvolvimento é gerenciado como problemas do GitHub e solicitações de puxar são bem -vindas. Se você estiver interessado em aprimorar o código, abra um problema para discutir as alterações ou aparecer e discuti -lo no fórum da comunidade.
Este projeto pode ser aberto em unidade para criar um ".UnityPackage".
Este projeto está licenciado sob a licença Apache-2.