Lingara Lingara 說明文件 學習指南 API 函式庫 應用程式 起造 嵌入 網頁版
語言: 閩南語

Unreal

這頁是對英文翻譯過來的。若兩篇無仝,以英文頁為準。 看英文頁

Unreal Engine 5 的 Lingara 外掛程式是一个 game-instance 子系統,建立佇玩家核心的 C 介面頂懸。伊佇玩家套件支援的五个平台頂懸行:Windows、macOS、Linux、Android 佮 iOS。主機猶未支援。

安裝外掛程式

逐个發行版攏會為逐个支援的引擎版本附一个外掛程式的 zip,名號是 LingaraEmbed-<semver>-UE5.<m>.zip。共你的引擎對應的彼个解壓縮到你專案的 Plugins/ 資料夾,了後佇編輯器內底啟用外掛程式。無其他物件愛安裝。

對你的伺服器提權杖

外掛程式從來袂保管密鑰。伊需要權杖的時,會廣播 OnTokenNeeded。送請求去你家己伺服器的權杖路由來回應伊;你的伺服器用一个伺服器套件簽發,閣用權杖佮伊的到期時間來回應,了後共兩項交予 ProvideToken。若你的伺服器無法度回應,就呼叫 TokenUnavailable,按呢咧等權杖的呼叫就會隨失敗,毋免等到逾時。

綁定你用的事件

核心佇伊家己的執行緒頂懸行網路 I/O。子系統佇伊家己的 tick 內底共伊清出來,一格上濟 MaxEventsPerTick 个事件(一个專案設定),閣共逐个佇一个 delegate 頂懸廣播。佇遊戲開始的時綁定你的遊戲需要的 delegate,了後才啟動子系統:

  • OnTokenNeeded,需要權杖的時;
  • OnNpcTurn,串流回覆的逐節(請看 NPC 對話);
  • OnPractice,逐个練習的更新(請看練習結果);
  • OnError,呼叫失敗的時。

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);
}