Unity developers spent most of 2025 wiring state machines and NavMesh agents together to fake intelligence in non-player characters. That approach still works for patrol routes and combat AI, but it falls apart the moment a player asks an NPC a question the designer never scripted. By September 2026, the fix has a name: pairing Unity’s engine-side systems with a hosted or local large language model, then routing the output through real-time text-to-speech. Studios building on Inworld, Convai, NVIDIA ACE, or a locally hosted Ollama model are shipping NPCs that hold an actual conversation, remember what the player said ten minutes earlier, and speak the answer out loud with matching lip movement.
This tutorial walks through building an AI-powered NPC in Unity 6 from a blank project to a working, voice-interactive character. You will wire up dialogue routing through an LLM, add streaming text-to-speech, sync basic lip movement, and give the character persistent memory across play sessions. The steps use Unity’s AI Navigation package for movement, a hosted LLM router for dialogue generation, and a local Ollama fallback for offline testing, so you can follow along whether your budget is zero or you are shipping a commercial title.
Why Unity AI NPCs Are Different From Old Dialogue Trees
A traditional Unity NPC dialogue system is a tree of pre-written lines with branching choices. Every response the player can trigger has to be written, translated, and voice-recorded ahead of time. That model has not disappeared, but it now sits next to a second approach: generative dialogue, where the NPC’s lines are produced at runtime by an LLM that has been given a personality prompt, a slice of world state, and the player’s actual input text.
The practical difference shows up in three places. First, the NPC can answer questions that were never anticipated by a writer, because the model is generating a response rather than selecting one from a list. Second, adding a new topic to an NPC’s knowledge means editing a prompt or a small context document rather than re-authoring a branching tree. Third, voice generation moves from pre-recorded audio files to streaming text-to-speech, which means the same character can say something new every single playthrough.
None of this replaces animation, pathfinding, or combat logic. A conversational NPC still needs Unity’s AI Navigation package for movement and a state machine for behavior like idle, alert, or fleeing. The LLM layer sits on top of that foundation and handles only the conversation itself, which keeps the system modular and easier to debug when something goes wrong.
Prerequisites and Software Versions
Confirm you have the following installed and accessible before starting. Version mismatches are the single most common cause of import errors in this kind of project, so check each one against your own install rather than assuming.
- Unity 6 (6000.0 LTS or newer) installed via Unity Hub, with the 3D (URP) template
- Unity AI Navigation package (installed through the Package Manager, version 2.0 or later)
- A code editor with C# support, such as Visual Studio 2022 or JetBrains Rider
- .NET SDK matching your Unity editor’s scripting runtime (Unity installs this automatically with most setups, but confirm under Edit > Preferences > External Tools)
- An account with a conversational AI platform for games, such as Inworld or Convai, both of which offer free developer tiers
- Optional: Ollama installed locally if you want an offline fallback model for dialogue generation without any API costs
- Optional: an ElevenLabs account if you want higher-fidelity streaming voice than your chosen platform’s built-in TTS
- A stable internet connection for any step that calls a hosted API
- At least 8GB of free disk space for the Unity project, plus 4-6GB more if you plan to run a local model through Ollama
Budget-wise, Inworld and Convai both let you build and test for free during development, with usage-based billing kicking in once you scale to real players. Running a small local model through Ollama costs nothing beyond your own hardware and electricity, which makes it the cheapest way to prototype dialogue logic before committing to a hosted platform.
Step 1: Create the Unity Project and Install AI Navigation
Open Unity Hub, create a new project using the 3D (URP) template, and name it something like AINpcDemo. Once the editor loads, open Window > Package Manager, switch the dropdown to Unity Registry, search for AI Navigation, and install it. This package replaces the legacy NavMesh workflow with a component-based bake system that works better with runtime-generated environments.
Add a simple test environment: a ground plane, a couple of walls or obstacles, and a capsule to represent your NPC. Select the ground and any static geometry, add a NavMeshSurface component, and click Bake in the inspector. This gives your NPC a walkable area before you touch any AI dialogue logic, so pathfinding and conversation can be debugged independently.
Step 2: Add a NavMeshAgent and Basic Movement
Select your NPC capsule, add a NavMeshAgent component, and set a reasonable speed (around 3.5 works for a walking human-scale character). Create a new C# script called NpcMovement and attach it. This script only needs to handle idle patrol and moving toward a target point when the dialogue system calls for it.
using UnityEngine;
using UnityEngine.AI;
public class NpcMovement : MonoBehaviour
{
public Transform[] patrolPoints;
public float waitTime = 3f;
private NavMeshAgent agent;
private int currentPoint = 0;
private float waitTimer = 0f;
private bool inConversation = false;
void Start()
{
agent = GetComponent();
if (patrolPoints.Length > 0)
agent.SetDestination(patrolPoints[0].position);
}
void Update()
{
if (inConversation) return;
if (!agent.pathPending && agent.remainingDistance = waitTime)
{
waitTimer = 0f;
currentPoint = (currentPoint + 1) % patrolPoints.Length;
agent.SetDestination(patrolPoints[currentPoint].position);
}
}
}
public void PauseForConversation(bool pause)
{
inConversation = pause;
agent.isStopped = pause;
}
}
Assign a few empty GameObjects as patrol points in the inspector. Press Play and confirm the NPC walks between them and pauses at each stop. This gives the conversation system a hook, PauseForConversation, that stops movement the moment dialogue starts.
Step 3: Choose Your Dialogue Backend (Hosted vs Local)
This is the decision that shapes the rest of the project. A hosted platform like Inworld or Convai bundles LLM routing, voice generation, and lip sync data into one API call, which is the fastest path to a working demo. Both platforms route requests to a mix of third-party and self-hosted models behind the scenes, so you are not locked into a single LLM vendor even though you only integrate one API.
Running dialogue generation locally through Ollama is the alternative if you want zero API cost during development, or if you are building for a platform where an always-on internet connection cannot be assumed. The tradeoff is that you handle voice synthesis and lip sync yourself, and local models generally need more prompt engineering to stay in character reliably compared to platforms tuned specifically for game dialogue.
The table below compares the three most common paths developers use for this stack right now.
| Approach | Setup time | Voice included | Runs offline | Best for |
|---|---|---|---|---|
| Inworld (hosted) | ~1-2 hours | Yes, built-in TTS + voice cloning | No | Voice-first NPCs, fastest time to demo |
| Convai (hosted) | ~1-2 hours | Yes, official Unity plugin | No | Lip-synced 3D characters, quick plugin integration |
| Ollama (local) | ~2-4 hours | No, add ElevenLabs or engine TTS separately | Yes | Zero-cost prototyping, offline builds, full control over the model |
This tutorial builds the hosted path first, then shows the local Ollama swap as an alternative in Step 9, so you can compare both without starting a second project.
Which LLM Should Power Your NPC’s Dialogue?
Neither Inworld nor Convai locks you into a single model. Both platforms sit in front of a router that forwards a request to whichever LLM best fits the job, and that routing layer is one of the fastest-moving parts of this stack right now. Inworld’s router, for example, can forward a request to more than 220 third-party models from providers including OpenAI, Anthropic, Google, Mistral, DeepSeek, xAI, Meta, and Groq, while also offering first-party hosted inference on open-weight models it runs itself for lower latency.
For early personality iteration, most developers start on a strong general-purpose third-party model, since these tend to follow a system prompt more reliably during the drafting phase. Once the character’s voice is locked in, production traffic often moves to a first-party hosted model, since these are tuned specifically for low time-to-first-token in a real-time conversation and cost less per exchange at scale. The table below breaks down where different model families tend to land in this workflow as of September 2026.
| Model family | Typical role in NPC dialogue | Strength |
|---|---|---|
| Claude Sonnet (Anthropic) | Personality drafting, complex lore reasoning | Strong instruction-following, stays in character over long sessions |
| GPT-series (OpenAI) | Personality drafting, general dialogue | Broad world knowledge, flexible tone |
| Gemma (Google, open-weight) | Production traffic on router-hosted inference | Low latency when self-hosted by the platform |
| DeepSeek V3.2/V4 | Cost-sensitive production traffic | Competitive quality at a lower per-token cost |
| GLM-5 series | Production traffic, multilingual NPCs | Strong performance-to-cost ratio for high-volume games |
| Local models via Ollama | Offline builds, zero-cost prototyping | No API cost, full control, but weaker default character consistency |
None of this requires you to write different code for different models. Because the router sits between your Unity plugin and the underlying LLM, switching a character from one model family to another is usually a dropdown change in the platform’s character dashboard rather than a code change in your Unity project. That is the actual advantage of building on Inworld or Convai instead of calling a single LLM vendor’s API directly: you get to swap the brain behind the character without touching the Unity-side integration at all.
Step 4: Set Up Your Inworld or Convai Account and API Key
Create a free developer account on your chosen platform. On Inworld, create a workspace, then create a new character through the Inworld Studio dashboard, giving it a name, a short backstory, and a personality description. Generate an API key from the workspace settings and keep it somewhere safe, you will paste it into Unity in the next step. Convai’s flow is similar: create a character in the Convai dashboard, define its knowledge base and personality, and copy the API key from your account settings.
Both platforms let you test the character directly in a web-based chat playground before touching Unity at all. Do that first. If the NPC’s personality drifts or gives answers you did not expect in the browser playground, fix the prompt there, since debugging prompt behavior is far faster in a text playground than inside the Unity editor with voice and animation running.
Step 5: Install the Unity SDK/Plugin
Both Inworld and Convai publish official Unity plugins that you import as a .unitypackage or through the Package Manager’s Git URL option, depending on the platform’s current distribution method. Follow the platform’s own installation page for the exact import steps, since plugin distribution details change between releases. After import, you will see a new component type available in the inspector, typically named something like InworldCharacter or ConvaiNPC, which handles the network call, streaming response, and audio playback for you.
Drag the plugin’s character component onto your NPC capsule alongside the NavMeshAgent and NpcMovement script from Step 2. Paste your API key and character ID into the component’s inspector fields. At this point you have not written any custom code yet, the plugin is doing the heavy lifting of session management.
Step 6: Trigger Conversation From Player Proximity
Add a trigger collider around the NPC, sized to roughly a 3-meter conversation radius. When the player enters it, pause the NPC’s patrol and open a simple dialogue UI. Create a new script called NpcConversationTrigger and attach it to the same GameObject as the collider.
using UnityEngine;
public class NpcConversationTrigger : MonoBehaviour
{
public NpcMovement movement;
public GameObject dialogueUI;
void OnTriggerEnter(Collider other)
{
if (!other.CompareTag("Player")) return;
movement.PauseForConversation(true);
dialogueUI.SetActive(true);
}
void OnTriggerExit(Collider other)
{
if (!other.CompareTag("Player")) return;
movement.PauseForConversation(false);
dialogueUI.SetActive(false);
}
}
Tag your player GameObject as Player if it is not already, and wire up the movement and dialogueUI references in the inspector. Press Play, walk into the trigger, and confirm the UI panel appears and the NPC stops patrolling.
Step 7: Send Player Input to the LLM and Display the Response
Add an input field and a send button to your dialogue UI, plus a text element to display the NPC’s reply. Wire the send button to a method that forwards the player’s typed text to the plugin’s character component, which handles the actual network request to the LLM behind the platform. Most plugins expose an event you subscribe to for the streaming response, since replies typically arrive token by token rather than all at once.
using UnityEngine;
using UnityEngine.UI;
public class DialogueUIController : MonoBehaviour
{
public InputField playerInputField;
public Text npcResponseText;
public MonoBehaviour npcCharacterComponent; // your plugin's character script
public void OnSendPressed()
{
string message = playerInputField.text;
if (string.IsNullOrWhiteSpace(message)) return;
// Call your plugin's send method here, e.g.:
// inworldCharacter.SendText(message);
// convaiNpc.SendTextData(message);
playerInputField.text = "";
npcResponseText.text = "...";
}
// Subscribe this to the plugin's onResponseReceived-style event
public void OnNpcResponse(string responseChunk)
{
npcResponseText.text += responseChunk;
}
}
The exact method names (SendText, SendTextData, or similar) differ between Inworld and Convai’s SDKs and change between plugin versions, so check the current API reference for your installed version rather than assuming the names above match exactly. The structure, sending player text and subscribing to a streaming response event, stays consistent across both platforms.
Step 8: Add Streaming Voice and Basic Lip Sync
If you are using Inworld or Convai’s bundled voice, this step is mostly configuration rather than code: select a voice in the character dashboard, enable the audio output option in the plugin component, and attach an AudioSource to your NPC. The plugin streams generated speech directly to that AudioSource as the response arrives.
For lip sync, both platforms expose viseme or blend shape data alongside the audio stream, which you map to your character model’s blend shapes (if using a humanoid model with ARKit-style blend shapes) or to a simpler jaw-bone rotation for lower-poly characters. If you want a higher-fidelity voice than the platform’s built-in option, ElevenLabs streaming TTS can be swapped in by intercepting the text response before the platform’s own TTS call and routing it to ElevenLabs’ streaming endpoint instead, then feeding the returned audio into the same AudioSource.
Studios building console-grade facial animation on top of this stack often reach for NVIDIA ACE, which adds audio-to-face animation models on top of the same conversational pipeline, though that is a heavier integration than most solo developers need for a first prototype.
Step 9: Add a Local Ollama Fallback for Offline Testing
To test dialogue logic without burning API credits, or to support a fully offline build, you can route requests to a locally running Ollama model instead of the hosted platform. Install Ollama, pull a small instruction-tuned model suited to real-time use, and run it locally so it exposes a REST endpoint on localhost.
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using System.Text;
public class OllamaNpcBridge : MonoBehaviour
{
private string endpoint = "http://localhost:11434/api/generate";
public string modelName = "llama3.2";
public void SendPrompt(string playerText, System.Action onLine)
{
StartCoroutine(PostToOllama(playerText, onLine));
}
private IEnumerator PostToOllama(string playerText, System.Action onLine)
{
string json = "{"model":"" + modelName + "","prompt":"" + playerText.Replace(""", "\"") + ""}";
var request = new UnityWebRequest(endpoint, "POST");
byte[] bodyRaw = Encoding.UTF8.GetBytes(json);
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
onLine?.Invoke(request.downloadHandler.text);
}
else
{
Debug.LogError("Ollama request failed: " + request.error);
}
}
}
This bridge sends a raw HTTP request to your local Ollama instance and returns the model’s text response, which you then feed into whichever TTS solution you attached in Step 8. Since Ollama returns streamed JSON lines by default, a production version of this script should parse each line as it arrives rather than waiting for the buffer to close, which is what the DownloadHandlerBuffer approach above does for simplicity. Swap in a custom DownloadHandlerScript if you need token-by-token streaming for lower perceived latency.
Step 10: Give the NPC Persistent Memory
Without memory, an NPC forgets the player’s name the moment the conversation UI closes, which breaks immersion fast. Both hosted platforms support session or player-keyed memory natively, typically by passing a consistent player ID with every request so the platform’s backend can retrieve prior conversation context. Enable this in the plugin’s session configuration rather than building your own memory store, since the hosted platforms already solve the harder problem of summarizing long conversation history so it fits in the model’s context window.
If you are running the local Ollama path, you need to build this yourself. The simplest version stores the last several exchanges in a local JSON file keyed by a save-slot ID, then prepends a short summary of that history to every new prompt. This gets expensive in tokens quickly, so most local implementations cap stored history to the last 6-10 exchanges and periodically summarize older ones into a short paragraph rather than keeping the raw transcript.
Step 11: Constrain the NPC’s Personality and Knowledge
An LLM-driven NPC without guardrails will happily break character, discuss topics that have nothing to do with your game world, or contradict lore you have already established. Fix this at the prompt level, not the code level. Write a system prompt that states the character’s name, role, personality traits, speech style, and a short list of things it knows and does not know. Keep this under a few hundred words. Longer system prompts do not make the character more consistent, they just eat into the token budget available for the actual conversation.
Add explicit boundaries: tell the model what to do if the player asks something outside its knowledge (deflect in character, rather than breaking the fourth wall), and what topics are off-limits entirely. Both Inworld and Convai support a “knowledge base” or “goals” feature that layers structured world facts on top of the personality prompt, which is more reliable than trying to cram everything into a single prompt block.
Step 12: Optimize for Latency and Player Experience
Response latency is the biggest immersion-breaker in this stack. A three-second pause before the NPC starts speaking feels broken even if the eventual answer is good. Reduce perceived latency with three techniques: stream text and audio as they arrive rather than waiting for the full response, show a short “thinking” animation or filler sound the instant the player submits their line, and keep your system prompt and knowledge base concise so the model has less to process before it starts generating.
If you are comparing cascaded voice pipelines (speech-to-text, then LLM, then text-to-speech run as separate sequential steps) against full-duplex or lower-latency configurations offered by your platform, test both under realistic network conditions before committing, since a demo recorded on a fast home connection often does not reflect what players on average connections will experience.
Step 13: Test, Build, and Ship
Run a full playtest pass focused specifically on adversarial player behavior: ask the NPC nonsense questions, try to get it to break character, repeat the same question multiple times, and walk away mid-response. Fix any breakage you find at the prompt level first, then at the code level for anything related to session handling or UI state. Once dialogue feels stable, do a full platform build (PC, console, or mobile depending on your target) and confirm your chosen platform’s SDK supports that build target, since not every conversational AI plugin has full parity across all of Unity’s build targets yet.
Before shipping, revisit your platform’s pricing page and estimate real usage costs based on expected concurrent players and average conversation length, since hosted LLM and voice costs scale with actual usage rather than being a flat fee like most Unity Asset Store plugins.
Deploying AI NPCs Across Different Game Platforms
The pipeline built in this tutorial behaves differently depending on where the finished build actually runs, and that matters more than most developers expect going in. On PC through Steam, a stable internet connection is close to a given, so the hosted Inworld or Convai path works with minimal extra handling beyond the network failure fallback covered in the troubleshooting section below.
Console platforms add a layer of certification requirements around network calls, data storage, and age-rated content that a purely scripted dialogue tree never had to deal with. If your NPC generates dialogue at runtime through a hosted LLM, plan for a certification review that will ask how you constrain the model’s output, since “the AI might say anything” is not an answer that clears a platform holder’s content review. This is exactly why the personality and knowledge constraints from Step 11 are not optional polish, they are effectively a certification requirement on any platform with a formal content review process.
Mobile builds bring their own constraint: players are far more likely to be on an inconsistent connection, whether that is spotty Wi-Fi or a data connection that drops mid-session. Design the dialogue UI to degrade gracefully, showing a clear retry state rather than a frozen “…” indicator, and consider caching a handful of pre-written fallback lines the NPC can use locally if the network request fails entirely, so a dropped connection reads as an in-world moment rather than a bug report.
Cloud gaming platforms sit in between: the game itself streams from a data center, so your NPC’s API calls to Inworld or Convai are often traveling server-to-server rather than from a player’s home connection, which can actually reduce the latency problems described in Step 12. If you are targeting a cloud gaming service, test your dialogue pipeline from a build running in that same hosting environment rather than assuming your local development machine’s network conditions carry over, since the two setups can produce noticeably different round-trip times.
Common Pitfalls When Building AI NPCs in Unity
These mistakes show up repeatedly in developer forums and Discord support channels for both hosted and local dialogue stacks.
- Skipping the text playground test. Testing a character’s personality for the first time inside Unity, with voice and animation running, makes debugging prompt issues far slower than catching them in the platform’s web-based chat tool first.
- Writing system prompts that are too long. A 2,000-word backstory does not make an NPC feel deeper, it just increases latency and leaves less room in the context window for actual conversation.
- Forgetting to pause movement during conversation. An NPC that keeps patrolling while mid-sentence looks broken and pulls players out of the moment.
- Not handling network failures gracefully. Hosted APIs will occasionally time out or rate-limit. Without a fallback line (“Sorry, say that again?”), a failed request looks like a game-breaking bug rather than a network hiccup.
- Ignoring token costs during development. Iterating on prompts by testing directly against a hosted, billed API adds up fast. Use the free playground tier or a local Ollama model for early iteration.
- Building memory storage as raw transcript logs. Feeding the entire conversation history into every new prompt blows through context limits and slows responses as sessions get longer. Summarize old history instead.
- Assuming plugin method names are stable across versions. SDK APIs for Inworld and Convai have changed between releases. Always check the current version’s reference docs rather than copying code from an older tutorial verbatim.
Example Output: What a Working Conversation Looks Like
Below is a representative exchange from a correctly configured NPC using a hosted platform with a tavern-keeper personality prompt and a small knowledge base about the game’s town.
Player: Hey, what's good to drink around here?
NPC: Ale's fresh, brewed it myself this morning. Two coppers a mug,
or three if you want it warmed. What'll it be?
Player: Have you seen anyone suspicious pass through lately?
NPC: Funny you ask. Fella in a grey cloak came through two nights back,
paid in silver he didn't want to explain. Didn't like the look
of him myself.
Player: What's your name again?
NPC: Told you before, it's Maren. You forget fast for someone
buying my ale.
Notice the third exchange: the NPC references having introduced itself earlier in the conversation, which is the persistent memory feature from Step 10 working correctly rather than the model inventing continuity by chance.
Troubleshooting Guide
Work through this list in order when something in the pipeline stops behaving as expected.
- NPC never responds after I press Send. Check the Unity Console for a network error first. Confirm your API key is pasted correctly and has not expired, and that your project has internet access if you are on a hosted platform.
- Response text appears but there is no audio. Confirm an AudioSource component is attached to the NPC and that the plugin’s audio output toggle is enabled in its inspector settings.
- NPC breaks character or references being an AI model. Tighten the system prompt with an explicit instruction never to acknowledge being an AI, and add a fallback in-character deflection line for off-topic questions.
- Movement does not pause when dialogue opens. Verify the trigger collider is set to Is Trigger, the player object carries the correct tag, and the movement reference is assigned in the inspector, not left null.
- Ollama requests time out locally. Confirm the Ollama service is actually running (check with a direct curl request to localhost:11434 outside Unity) and that the model name in your script matches a model you have already pulled.
- Lip sync looks disconnected from the audio. Blend shape or viseme data usually arrives on a slight delay relative to raw audio playback. Check whether your plugin exposes a sync offset setting, most do.
- Latency feels too high to be usable. Shorten your system prompt and knowledge base, enable streaming if it is not already on, and add a filler “thinking” cue the instant the player submits input so the wait feels shorter.
- Build fails or the plugin throws errors on a specific platform target. Check the plugin vendor’s supported platforms list before investing further, since Unity build target support varies by SDK and by version, and console support in particular often lags behind PC support.
Advanced Tips for Production-Ready AI NPCs
Once the basic pipeline works, a few refinements separate a tech demo from something you can ship. Route different NPC types through different models rather than a single model for every character. A background market vendor can use a smaller, cheaper model since players rarely have deep conversations with them, while a main questgiver can use a stronger model that justifies its higher cost through richer, more consistent dialogue.
Cache common responses where it makes sense. If your NPC gives the same greeting to every new player on first contact, do not regenerate that line through the LLM every time, since a cached or pre-recorded greeting saves both latency and API cost for the highest-frequency interaction in the game.
Log conversation transcripts (with player consent, respecting your platform’s and region’s privacy requirements) during a closed beta. Reviewing real player questions against your NPC’s actual answers reveals prompt gaps far faster than internal QA alone, since players ask things designers rarely think to test for.
Finally, treat your system prompts as versioned game content, not throwaway configuration. Store them in source control alongside your Unity project, and review changes the same way you would review a code change, since a small prompt edit can shift a character’s entire personality in ways that are easy to miss during a quick playtest.
Complete Working Project Structure
By following all thirteen steps above, your project folder should contain the following pieces working together as one system.
| Component | Script or asset | Handles |
|---|---|---|
| Movement | NpcMovement.cs + NavMeshAgent | Patrol, pausing during conversation |
| Trigger | NpcConversationTrigger.cs + Collider | Opening/closing dialogue UI on proximity |
| Dialogue UI | DialogueUIController.cs + Canvas | Player input, displaying streamed response |
| Hosted LLM + voice | Inworld or Convai plugin component | Dialogue generation, TTS, lip sync data |
| Local fallback | OllamaNpcBridge.cs | Offline dialogue generation via REST call |
| Memory | Platform session config or local JSON store | Persistent context across conversations |
This structure keeps each concern (movement, triggering, UI, and dialogue generation) in its own script, which makes it straightforward to swap the LLM backend later without touching your movement or trigger logic at all. That separation is what lets you prototype cheaply with a local Ollama model in Step 9 and later swap to a hosted platform for production without a rewrite.
For a deeper look at Unity’s own machine learning tooling beyond conversational NPCs, the ML-Agents toolkit on GitHub covers training in-engine agents for behaviors like combat or navigation using reinforcement learning, which is a complementary but separate system from the LLM dialogue pipeline built in this tutorial.
Frequently Asked Questions
Do I need to know machine learning to build an AI NPC in Unity?
No. Hosted platforms like Inworld and Convai handle the model hosting, routing, and voice generation behind an API you call from C#. You need to understand prompt writing and basic Unity scripting, not model training or machine learning theory.
How much does it cost to run an AI NPC in a shipped game?
Both major hosted platforms bill based on usage, typically tied to conversation volume or generated audio minutes, with a free tier for development. Costs scale with your concurrent player count and how chatty your NPCs are, so estimate real usage before launch rather than assuming the free development tier covers production traffic.
Can I run AI NPC dialogue completely offline?
Yes, by routing dialogue generation through a locally hosted model with Ollama as shown in Step 9. You lose the built-in voice and lip sync data that hosted platforms provide, so you need to add your own TTS and viseme mapping separately if you want a fully offline voice pipeline.
Which is better for a first project, Inworld or Convai?
Both work well and offer official Unity plugins. Convai leans toward quick plugin-based integration with strong lip-sync support out of the box. Inworld leans toward flexible model routing across many third-party and first-party LLMs. Try both platforms’ free tiers on a small test scene before committing your whole project to one.
Will an LLM-driven NPC say something inappropriate or break my game’s rating?
It can, if the system prompt and knowledge base are not constrained carefully, since the underlying model was trained on broad internet text. Reduce this risk with a tight system prompt, explicit topic boundaries, platform-level content filtering where available, and a closed beta test focused on adversarial player input before wide release.
Do I need Unity 6 specifically, or does this work on older Unity versions?
The AI Navigation package and current plugin versions for Inworld and Convai target Unity 6 and recent 2022 LTS releases. Older Unity versions may work with older plugin releases, but you should check your target platform’s current compatibility notes before starting a new project on an older editor version.
How do I keep the NPC from repeating the same lines to every player?
Because responses are generated at runtime rather than played from a fixed list, exact repetition across playthroughs is uncommon by default. If you notice repetitive phrasing, it usually means the system prompt is too rigid or the temperature/creativity setting on your platform is set too low, both of which are adjustable in the character configuration.