Lingara Lingara 說明文件 學習指南 API 程式庫 App 建立 嵌入 網頁版
語言: 粵語

Unreal

呢頁係由英文翻譯過嚟嘅。如果兩個版本有出入,以英文頁為準。 睇英文頁

Unreal Engine 5 用嘅 Lingara 外掛程式係一個遊戲執行個體子系統,建基於玩家核心嘅 C 介面。佢喺玩家套件支援嘅五個平台上面行:Windows、macOS、Linux、Android 同 iOS。暫時仲未支援遊戲主機。

安裝外掛程式

每次發行都會為每個支援嘅引擎版本附上一個外掛程式 zip 檔,命名做 LingaraEmbed-<semver>-UE5.<m>.zip。將啱你引擎嗰個解壓縮到你專案嘅 Plugins/ 資料夾,然後喺編輯器度啟用個外掛程式。唔使再裝其他任何嘢。

由你部伺服器攞權杖

外掛程式永遠唔會持有密鑰。佢需要權杖嗰陣,會廣播 OnTokenNeeded。回應方法係向你自己部伺服器嘅權杖路由傳送 POST 請求,伺服器用伺服器套件簽發權杖,再回覆權杖同佢嘅到期時間,然後將兩樣交畀 ProvideToken。如果你部伺服器回應唔到,就呼叫 TokenUnavailable,等緊權杖嘅呼叫就會即刻失敗,而唔係等到逾時。

綁定你用嘅事件

核心喺佢自己嘅執行緒上面做網絡 I/O。子系統喺佢自己嘅 tick 入面清空佇列,每個畫格最多 MaxEventsPerTick 個事件(一項專案設定),然後喺委派上面逐個廣播。喺遊戲開始嗰陣綁定你個遊戲需要嘅委派,然後啟動子系統:

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