Lingara Lingara Tài liệu Cẩm nang API Thư viện Ứng dụng Tạo Nhúng Ứng dụng web
Ngôn ngữ: Tiếng Việt

Unreal

Trang này được dịch từ tiếng Anh. Nếu hai bản khác nhau, trang tiếng Anh là bản đúng. Đọc trang tiếng Anh

Plugin Lingara cho Unreal Engine 5 là một subsystem cấp game instance, xây dựng trên giao diện C của lõi người chơi. Plugin chạy trên năm nền tảng mà các bộ công cụ người chơi hỗ trợ: Windows, macOS, Linux, Android và iOS. Máy chơi game console hiện chưa được hỗ trợ.

Cài đặt plugin

Mỗi bản phát hành chứa một tệp zip của plugin cho từng phiên bản engine được hỗ trợ, có tên LingaraEmbed-<semver>-UE5.<m>.zip. Giải nén tệp dành cho engine của bạn vào thư mục Plugins/ của dự án, rồi bật plugin trong trình chỉnh sửa. Không cần cài thêm gì khác.

Lấy mã từ máy chủ của bạn

Plugin không bao giờ giữ khóa bí mật. Khi cần một mã, nó phát OnTokenNeeded. Hãy trả lời bằng cách gửi POST tới tuyến cấp mã của máy chủ của chính bạn; máy chủ cấp mã bằng bộ công cụ máy chủ và trả lời bằng mã cùng thời điểm hết hạn của nó, rồi chuyển cả hai cho ProvideToken. Nếu máy chủ của bạn không thể trả lời, hãy gọi TokenUnavailable để các lệnh gọi đang chờ mã thất bại ngay lập tức thay vì hết thời gian chờ.

Gắn các sự kiện bạn dùng

Lõi chạy I/O mạng trên luồng riêng của nó. Subsystem rút hàng đợi từ tick của chính nó, tối đa MaxEventsPerTick sự kiện mỗi khung hình (một cài đặt dự án), và phát từng sự kiện trên một delegate. Hãy gắn các delegate trò chơi của bạn cần khi bắt đầu chơi, rồi khởi động subsystem:

  • OnTokenNeeded, khi cần một mã;
  • OnNpcTurn, cho mỗi phần của một câu trả lời được truyền về (xem hội thoại NPC);
  • OnPractice, cho mỗi cập nhật luyện tập (xem kết quả luyện tập);
  • OnError, khi một lệnh gọi thất bại.

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