Một NPC AI trong Unity gồm bốn khâu nối tiếp: nhận giọng nói và chuyển thành chữ (STT), gửi tới mô hình ngôn ngữ lớn (LLM) qua một máy chủ trung gian, nhận câu trả lời có cấu trúc, rồi phát giọng nói (TTS) kèm hoạt ảnh và khẩu hình. Điểm mấu chốt là không đặt API key trong ứng dụng, giới hạn phạm vi kiến thức của NPC và thiết kế để che độ trễ.
NPC AI trong Unity gồm những thành phần nào?

Một NPC AI trong Unity là nhân vật 3D có “bộ não” là LLM, “tai” là STT, “miệng” là TTS và “cơ thể” là hệ thống hoạt ảnh của Unity. Bài NPC thông minh dùng LLM đã giải thích khái niệm và rủi ro; bài này đi vào cách lắp ráp cụ thể.
Định nghĩa — System prompt: Đoạn chỉ dẫn cố định gửi kèm mọi lượt hội thoại, mô tả vai trò, tính cách, phạm vi kiến thức và quy tắc trả lời của NPC. Người chơi không nhìn thấy nhưng nó định hình toàn bộ hành vi nhân vật.
| Thành phần | Vai trò | Lựa chọn phổ biến | Chạy ở đâu |
|---|---|---|---|
| STT (Speech-to-Text) | Chuyển giọng người chơi thành chữ | Dịch vụ đám mây, mô hình họ Whisper | Đám mây hoặc trên thiết bị |
| LLM | Hiểu câu hỏi, sinh câu trả lời | API thương mại hoặc mô hình mở tự lưu trữ | Backend |
| RAG | Tra cứu tài liệu nội bộ | Cơ sở dữ liệu vector | Backend |
| TTS (Text-to-Speech) | Chuyển chữ thành giọng nói | Dịch vụ TTS có giọng tiếng Việt | Đám mây hoặc thiết bị |
| Hoạt ảnh và khẩu hình | Cử chỉ, biểu cảm, nhép môi | Animator, blendshape, plugin lip-sync | Unity |
Bước 1: Thiết kế nhân vật và phạm vi hội thoại
Thiết kế nhân vật là trả lời rõ “NPC này là ai, biết gì, được làm gì và không được nói gì” trước khi viết mã.
- Mục tiêu:
NPC giúp người dùng đạt điều gì? Ví dụ: hướng dẫn khách tham quan
bảo tàng ảo
, đóng vai khách hàng khó tính trong bài đào tạo bán hàng. - Tính cách và giọng điệu:
xưng hô thế nào, trang trọng hay thân mật, câu trả lời dài tối đa bao nhiêu. - Phạm vi kiến thức:
liệt kê chủ đề được nói và tài liệu nguồn. - Danh sách hành động:
các hoạt ảnh NPC được kích hoạt như chào, chỉ tay, gật đầu, dẫn đường. - Ranh giới:
chủ đề cấm, câu từ chối lịch sự, khi nào chuyển sang nhân viên thật. - Kịch bản kiểm thử:
30–50 câu hỏi mẫu, gồm cả câu cố tình “phá” để kiểm tra.
Ví dụ system prompt rút gọn cho một NPC hướng dẫn viên:
Bạn là Lan, hướng dẫn viên ảo của bảo tàng. Xưng "em", gọi khách là "anh/chị".
Chỉ trả lời về hiện vật, lịch sử và dịch vụ của bảo tàng dựa trên TÀI LIỆU được cung cấp.
Nếu không có thông tin, nói rằng em chưa có dữ liệu và gợi ý hỏi nhân viên.
Trả lời tối đa 3 câu. Luôn trả về JSON:
{"say": "...", "emotion": "neutral|happy|thinking|sorry", "action": "none|wave|point|nod"}
Bước 2: Dựng backend trung gian
Backend trung gian là máy chủ nằm giữa ứng dụng Unity và nhà cung cấp LLM, giữ API key, ghép system prompt, tra cứu tài liệu và kiểm tra đầu ra. Đây là bước không được bỏ qua trong sản phẩm thật.
Mọi chuỗi bí mật trong bản build Unity đều có thể bị trích xuất; backend còn cho phép đổi mô hình, chỉnh prompt mà không phải phát hành lại ứng dụng.
Backend tối thiểu cần làm:
– Nhận npcId và lịch sử hội thoại từ client.
– Ghép system prompt theo npcId, thêm đoạn tài liệu liên quan nếu dùng RAG. Xem cách xây RAG trong ứng dụng XR.
– Gọi LLM, yêu cầu định dạng JSON (nhiều nhà cung cấp hỗ trợ chế độ đầu ra có cấu trúc).
– Kiểm tra JSON hợp lệ, lọc nội dung, chuẩn hóa action theo danh sách cho phép.
– Ghi log ẩn danh để cải thiện prompt.
Bước 3: Kết nối Unity với backend
Unity gửi lượt hội thoại tới backend bằng UnityWebRequest và nhận về JSON chứa lời thoại, cảm xúc và hành động. Script dưới đây dùng JsonUtility có sẵn, chạy được trên các phiên bản Unity phổ biến.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
[Serializable] public class ChatMessage { public string role; public string content; }
[Serializable] public class ChatRequest { public string npcId; public List<ChatMessage> messages; }
[Serializable] public class NpcReply { public string say; public string emotion; public string action; }
public class NpcBrain : MonoBehaviour
{
[SerializeField] private string endpoint = "https://api.example.com/npc/chat";
[SerializeField] private string npcId = "huong-dan-vien-lan";
[SerializeField] private int maxHistory = 10;
private readonly List<ChatMessage> history = new List<ChatMessage>();
public event Action<NpcReply> OnReply;
public void Ask(string playerText)
{
StartCoroutine(SendRoutine(playerText));
}
private IEnumerator SendRoutine(string playerText)
{
history.Add(new ChatMessage { role = "user", content = playerText });
if (history.Count > maxHistory)
history.RemoveRange(0, history.Count - maxHistory);
string body = JsonUtility.ToJson(new ChatRequest { npcId = npcId, messages = history });
using (var req = new UnityWebRequest(endpoint, "POST"))
{
req.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body));
req.downloadHandler = new DownloadHandlerBuffer();
req.SetRequestHeader("Content-Type", "application/json");
req.timeout = 15;
yield return req.SendWebRequest();
if (req.result != UnityWebRequest.Result.Success)
{
OnReply?.Invoke(new NpcReply { say = "Xin lỗi, em chưa nghe rõ. Anh/chị hỏi lại giúp em nhé?", emotion = "sorry", action = "none" });
yield break;
}
NpcReply reply = JsonUtility.FromJson<NpcReply>(req.downloadHandler.text);
history.Add(new ChatMessage { role = "assistant", content = reply.say });
OnReply?.Invoke(reply);
}
}
}
Một script khác lắng nghe OnReply để hiển thị phụ đề, gọi TTS và kích hoạt hoạt ảnh. Chỉ chấp nhận action nằm trong danh sách đã định nghĩa:
private static readonly HashSet<string> AllowedActions = new HashSet<string> { "wave", "point", "nod" };
private void HandleReply(NpcReply r)
{
subtitle.text = r.say;
if (AllowedActions.Contains(r.action)) animator.SetTrigger(r.action);
animator.SetInteger("Emotion", EmotionToIndex(r.emotion));
}
Bước 4: Giọng nói, hoạt ảnh và xử lý độ trễ

Giọng nói và hoạt ảnh quyết định NPC có “sống” hay không, còn độ trễ quyết định người dùng có kiên nhẫn trò chuyện hay không.
Thu giọng nói
Dùng chế độ nhấn-để-nói (push-to-talk) để tránh thu nhầm tạp âm. Lớp Microphone của Unity cho phép ghi âm, ví dụ Microphone.Start(null, false, 10, 16000) ghi tối đa 10 giây ở 16 kHz, tần số mẫu phổ biến cho STT. Sau đó chuyển dữ liệu âm thanh sang WAV và gửi tới dịch vụ STT. Trên kính VR, cần khai báo quyền micro theo yêu cầu của nền tảng.
Phát giọng và khẩu hình
Chọn giọng TTS tiếng Việt phù hợp vùng miền và tính cách nhân vật; bài AI giọng nói cho nhân vật ảo so sánh các hướng lựa chọn. Khẩu hình có thể dựa trên phân tích âm thanh thời gian thực (các plugin lip-sync) hoặc dữ liệu viseme do dịch vụ TTS trả về. Chi tiết xem AI lip-sync và biểu cảm khuôn mặt.
Che độ trễ
| Kỹ thuật | Cách làm | Hiệu quả |
|---|---|---|
| Hoạt ảnh “đang nghĩ” | NPC nghiêng đầu, gật nhẹ ngay khi người dùng dừng nói | Người dùng biết hệ thống đang xử lý |
| Câu đệm | Phát sẵn “Để em xem nào…” từ file âm thanh có sẵn | Lấp khoảng lặng đầu tiên |
| Streaming | Nhận câu trả lời theo từng đoạn, TTS câu đầu tiên ngay | Giảm thời gian chờ cảm nhận |
| Câu trả lời ngắn | Giới hạn 2–3 câu trong system prompt | Giảm thời gian sinh và phát |
| Bộ nhớ đệm | Lưu sẵn câu trả lời cho câu hỏi phổ biến | Gần như tức thì |
Góc kỹ thuật cho đội phát triển
Phần này tổng hợp các quyết định kiến trúc khi đưa NPC AI từ bản demo sang sản phẩm.
Quản lý ngữ cảnh: giữ cửa sổ N lượt gần nhất như mã mẫu, để backend tóm tắt lượt cũ thành “bộ nhớ dài hạn” ngắn gọn.
Đầu ra có cấu trúc: JsonUtility không hỗ trợ dictionary và yêu cầu khớp tên trường. Nếu cần JSON linh hoạt hơn, dùng gói Newtonsoft Json cho Unity. Luôn có nhánh xử lý khi JSON hỏng: hiển thị câu dự phòng thay vì để NPC “đơ”.
Streaming: để phát giọng sớm, backend có thể trả dữ liệu dạng Server-Sent Events hoặc WebSocket; phía Unity cần DownloadHandlerScript tùy biến hoặc thư viện WebSocket. Hãy cắt câu theo dấu chấm để gửi TTS từng câu.
Chạy trên thiết bị: với yêu cầu ngoại tuyến hoặc riêng tư cao, có thể chạy mô hình nhỏ ngay trên máy qua gói suy luận AI của Unity (Sentis, tên gọi có thể thay đổi theo phiên bản) hoặc thư viện bên thứ ba. Đánh đổi là chất lượng hội thoại và nhiệt độ thiết bị; tham khảo AI chạy trên kính XR.
Kiểm thử: chạy bộ câu hỏi mẫu tự động mỗi lần đổi prompt hoặc mô hình; giới hạn tần suất gọi theo người dùng để tránh lạm dụng chi phí.
Ứng dụng thực tế tại Việt Nam

NPC AI trong Unity đặc biệt hữu ích cho đào tạo và trải nghiệm thương hiệu tại Việt Nam, nơi nội dung cần tiếng Việt tự nhiên và kiến thức đặc thù. Các ví dụ dưới đây là kịch bản minh họa.
Đào tạo nhân viên ngân hàng, bán lẻ: NPC đóng vai khách hàng với nhiều tính cách khác nhau để nhân viên luyện xử lý khiếu nại. Sau mỗi phiên, backend chấm điểm theo tiêu chí do bộ phận đào tạo định nghĩa.
Bảo tàng và điểm du lịch ảo: NPC hướng dẫn viên trả lời câu hỏi về hiện vật trong tour ảo, có thể kết hợp với tour 360 như một lớp tương tác.
Lưu ý bối cảnh: cần thử nghiệm kỹ với giọng nói vùng miền và cách nói pha tiếng Anh, vì độ chính xác STT có thể khác nhau. Nếu dữ liệu hội thoại chứa thông tin cá nhân, hãy tham vấn chuyên gia pháp lý về quy định bảo vệ dữ liệu hiện hành.
Câu hỏi thường gặp (FAQ)
Có thể gọi API LLM trực tiếp từ Unity không?
Về kỹ thuật thì được, nhưng không nên cho sản phẩm phát hành vì API key có thể bị trích xuất từ bản build. Chỉ làm vậy trong bản thử nghiệm nội bộ.
NPC AI có chạy được trên kính VR độc lập không?
Có, theo mô hình client gọi backend qua mạng. Chạy toàn bộ trên kính khả thi với mô hình nhỏ nhưng chất lượng hội thoại hạn chế hơn và cần tối ưu nhiệt, pin.
Chi phí vận hành NPC AI tính thế nào?
Chủ yếu theo lượng token LLM, số phút STT và số ký tự TTS, cộng chi phí máy chủ. Mức cụ thể tùy nhà cung cấp và lưu lượng, chỉ nên coi ước tính ban đầu là tham khảo.
Làm sao để NPC không bịa thông tin?
Giới hạn phạm vi trong system prompt, cung cấp tài liệu nguồn qua RAG, yêu cầu NPC thừa nhận khi không biết và kiểm thử bằng bộ câu hỏi mẫu. Không có cách nào loại bỏ hoàn toàn rủi ro, nên cần giám sát định kỳ.
Nên dùng Unity hay Unreal cho NPC AI?
Cả hai đều làm được vì phần AI nằm chủ yếu ở backend. Chọn engine theo đội ngũ và nền tảng mục tiêu.
Kết luận
Xây NPC AI trong Unity không khó ở khâu gọi API, mà ở thiết kế nhân vật, kiến trúc backend an toàn, kiểm soát đầu ra và che độ trễ. Bắt đầu với một NPC, một phạm vi hẹp và bộ câu hỏi kiểm thử rõ ràng, rồi mở rộng dần. Nếu bạn đang cân nhắc đưa nhân vật hội thoại vào dự án đào tạo hay trải nghiệm thương hiệu, hãy liên hệ đội ngũ tư vấn để được đánh giá nhu cầu.





