Lingara Lingara Documentation Guides API Bibliothèques Applications Créer Intégration Application web
Langue: Français

Unreal

Cette page est traduite de l'anglais. En cas de différence, la page anglaise fait foi. Lire la page en anglais

Le plugin Lingara pour Unreal Engine 5 est un sous-système d’instance de jeu construit sur l’interface C du cœur joueur. Il fonctionne sur les cinq plateformes prises en charge par les kits joueur : Windows, macOS, Linux, Android et iOS. Les consoles ne sont pas encore prises en charge.

Installer le plugin

Chaque version contient une archive zip du plugin pour chaque version du moteur prise en charge, nommée LingaraEmbed-<semver>-UE5.<m>.zip. Décompressez celle qui correspond à votre moteur dans le dossier Plugins/ de votre projet, puis activez le plugin dans l’éditeur. Il n’y a rien d’autre à installer.

Obtenir des jetons depuis votre serveur

Le plugin ne détient jamais de secret. Lorsqu’il a besoin d’un jeton, il diffuse OnTokenNeeded. Répondez-y en envoyant une requête à la route de jetons de votre propre serveur, qui émet le jeton avec un kit serveur et répond avec le jeton et son expiration, puis transmettez les deux à ProvideToken. Si votre serveur ne peut pas répondre, appelez TokenUnavailable afin que les appels en attente d’un jeton échouent immédiatement au lieu d’expirer.

Lier les événements que vous utilisez

Le cœur exécute ses E/S réseau sur son propre thread. Le sous-système le vide depuis son propre tick, au plus MaxEventsPerTick événements par frame (un paramètre du projet), et diffuse chacun sur un délégué. Liez les délégués dont votre jeu a besoin au début de la partie, puis démarrez le sous-système :

  • OnTokenNeeded, lorsqu’un jeton est nécessaire ;
  • OnNpcTurn, pour chaque morceau d’une réponse en flux (voir Dialogue de PNJ) ;
  • OnPractice, pour chaque mise à jour de pratique (voir résultats de pratique) ;
  • OnError, lorsqu’un appel échoue.

Unreal C++

// Your own server mints the token: never put a client secret in a game.
void ALingaraEmbedSnippetActor::HandleTokenNeeded(const FLingaraTokenNeeded& Event)
{
	const TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest();
	Request->SetVerb(TEXT("POST"));
	Request->SetURL(TokenUrl);
	Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));
	Request->SetContentAsString(TEXT("{}"));
	Request->OnProcessRequestComplete().BindUObject(this, &ALingaraEmbedSnippetActor::HandleTokenResponse);
	Request->ProcessRequest();
}

void ALingaraEmbedSnippetActor::HandleTokenResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bConnected)
{
	ELingaraCallResult Result;
	FLingaraEmbedError Error;
	TSharedPtr<FJsonObject> Body;
	FString Token;
	FString ExpiresAt;
	const bool bOk = bConnected && Response.IsValid() && EHttpResponseCodes::IsOk(Response->GetResponseCode())
		&& FJsonSerializer::Deserialize(TJsonReaderFactory<TCHAR>::Create(Response->GetContentAsString()), Body)
		&& Body->TryGetStringField(TEXT("token"), Token) && Body->TryGetStringField(TEXT("expires_at"), ExpiresAt);
	if (bOk)
	{
		Lingara()->ProvideToken(Token, ExpiresAt, Result, Error);
	}
	else
	{
		// Fail the waiting calls now rather than at the core's timeout.
		Lingara()->TokenUnavailable(TEXT("the token endpoint failed"), Result, Error);
	}
}

Unreal C++

// The subsystem drains the core's queue from its own tick (at most
// MaxEventsPerTick a frame, from Project Settings): bind the events you use.
void ALingaraEmbedSnippetActor::BeginPlay()
{
	Super::BeginPlay();
	ULingaraEmbedSubsystem* Subsystem = Lingara();
	Subsystem->OnTokenNeeded.AddDynamic(this, &ALingaraEmbedSnippetActor::HandleTokenNeeded);
	Subsystem->OnNpcTurn.AddDynamic(this, &ALingaraEmbedSnippetActor::HandleNpcTurn);
	Subsystem->OnPractice.AddDynamic(this, &ALingaraEmbedSnippetActor::HandlePractice);
	Subsystem->OnError.AddDynamic(this, &ALingaraEmbedSnippetActor::HandleError);

	FLingaraEmbedConfig Config;
	Config.MaxEventsPerTick = 256;
	ELingaraCallResult Result;
	FLingaraEmbedError Error;
	Subsystem->Start(Config, Result, Error);
}

void ALingaraEmbedSnippetActor::HandleError(const FLingaraEmbedError& Error)
{
	UE_LOG(LogTemp, Warning, TEXT("Lingara %s: %s"), *Error.KindName, *Error.Message);
}