NPC Conversations
Create AI-powered NPC dialogues in Unreal Engine
NPC Conversations
UPlayKitNPCClient is an Actor Component that manages AI-powered NPC conversations with automatic history tracking, memory, actions, and reply predictions.
Setup
Blueprint
- Select your NPC Actor and click Add Component → search for PlayKit NPC Client
- Call Setup NPC (from PlayKit Blueprint Library) in Begin Play
- Set the Character Design property in the Details panel
- Bind to On Response and On Error events
C++
#include "NPC/PlayKitNPCClient.h"
#include "PlayKitBlueprintLibrary.h"
UCLASS()
class ANPCActor : public AActor
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere)
UPlayKitNPCClient* NPCClient;
virtual void BeginPlay() override;
UFUNCTION()
void HandleNPCResponse(const FNPCResponse& Response);
};
void ANPCActor::BeginPlay()
{
Super::BeginPlay();
NPCClient = FindComponentByClass<UPlayKitNPCClient>();
UPlayKitBlueprintLibrary::SetupNPC(NPCClient);
NPCClient->SetCharacterDesign(TEXT(
"You are Gareth, a grizzled blacksmith in a medieval village. "
"You speak in a gruff but friendly manner. "
"You can forge weapons and armor, and know local rumors."
));
NPCClient->OnResponse.AddDynamic(this, &ANPCActor::HandleNPCResponse);
}
void ANPCActor::HandleNPCResponse(const FNPCResponse& Response)
{
if (Response.bSuccess)
DialogueWidget->SetNPCText(Response.Content);
}Basic Conversation
NPCClient->Talk(TEXT("Hello, what do you sell?"));The NPC automatically maintains conversation history across calls. Subsequent messages build on prior context.
Streaming Responses
void ANPCActor::BeginPlay()
{
Super::BeginPlay();
NPCClient = FindComponentByClass<UPlayKitNPCClient>();
UPlayKitBlueprintLibrary::SetupNPC(NPCClient);
NPCClient->OnStreamChunk.AddDynamic(this, &ANPCActor::HandleChunk);
NPCClient->OnStreamComplete.AddDynamic(this, &ANPCActor::HandleComplete);
}
void ANPCActor::HandleChunk(const FString& Chunk)
{
DialogueWidget->AppendText(Chunk);
}
void ANPCActor::StartConversation()
{
NPCClient->TalkStream(TEXT("Tell me the legend of this land"));
}Character Design
The character design defines the NPC's personality, knowledge, and behavioral constraints.
NPCClient->SetCharacterDesign(TEXT(
"You are Luna, a mysterious fortune teller. "
"You speak in riddles and metaphors. "
"You know secrets about the player's destiny but reveal them cryptically."
));For NPCs with strict knowledge boundaries:
NPCClient->SetCharacterDesign(TEXT(
"You are a guard stationed at the castle gate. "
"You only know about the castle schedule, your captain Sir Roland, "
"and recent bandit sightings in the forest. "
"Decline to discuss anything outside your knowledge."
));Memory System
Persist facts across conversation resets using named memory entries.
NPCClient->SetMemory(TEXT("PlayerName"), TEXT("Alex"));
NPCClient->SetMemory(TEXT("LastQuest"), TEXT("found the lost amulet"));
FString PlayerName = NPCClient->GetMemory(TEXT("PlayerName"));Memory is included in every request — ideal for information that should persist even after ClearHistory().
History Management
TArray<FNPCMessage> History = NPCClient->GetHistory();
NPCClient->ClearHistory();
NPCClient->RevertHistory();
FString SaveData = NPCClient->SaveHistory();
NPCClient->LoadHistory(SaveData);NPC Actions
NPCs can trigger game actions through structured responses. When the NPC decides to perform an action, OnActionTriggered fires with the action name and parameters.
NPCClient->OnActionTriggered.AddDynamic(this, &ANPCActor::HandleAction);
void ANPCActor::HandleAction(const FNPCActionCall& ActionCall)
{
if (ActionCall.Name == TEXT("give_item"))
{
FString ItemId = ActionCall.Arguments.FindRef(TEXT("item_id"));
PlayerInventory->AddItem(ItemId);
NPCClient->ReportActionResult(ActionCall.CallId, TEXT("Item given successfully"));
}
}Define available actions in the character design:
NPCClient->SetCharacterDesign(TEXT(
"You are a quest giver. "
"When you want to give the player an item, call the give_item action with the item_id. "
"Available items: health_potion, iron_sword, map."
));Reply Predictions
Generate suggested player responses to display as dialogue options.
NPCClient->bAutoGenerateReplyPredictions = true;
NPCClient->PredictionCount = 4;
NPCClient->OnReplyPredictionsGenerated.AddDynamic(this, &ANPCActor::HandlePredictions);
void ANPCActor::HandlePredictions(const TArray<FString>& Predictions)
{
for (const FString& Option : Predictions)
CreateDialogueButton(Option);
}To generate predictions on demand:
NPCClient->GenerateReplyPredictions(3);Temperature
NPCClient->SetTemperature(0.3f); // Consistent, predictable responses
NPCClient->SetTemperature(0.9f); // Creative, varied responsesEvents Reference
| Event | Parameters | Description |
|---|---|---|
OnResponse | FNPCResponse Response | Fired when NPC responds (non-streaming) |
OnStreamChunk | FString Chunk | Fired for each streaming text chunk |
OnStreamComplete | FString FullContent | Fired when streaming finishes |
OnActionTriggered | FNPCActionCall ActionCall | Fired when NPC triggers an action |
OnReplyPredictionsGenerated | TArray<FString> Predictions | Fired when reply predictions are ready |
OnError | FString ErrorCode, FString ErrorMessage | Fired on request failure |
Next Steps
- Speech Recognition — voice input for NPC dialogue
- Text Generation — stateless chat without history
- API Reference — complete SDK reference