AI Gameplay
Unity AI
Function Calling
Behavior Trees
Unity C#
Game Systems
AI NPCs

Production AI NPC Systems in Unity (Part 2): Structured JSON Function Calling & Behavior Trees

4 min read
Eshan Naithani

In Part 1 of this masterclass, we established the inference pipeline comparing Local vs. Cloud LLMs in Unity.

However, having an AI character output raw conversational prose (e.g., "I'm going to walk over to the blacksmith and buy a sword") is useless for a 3D game engine. To make the AI interact with the game world, the LLM must return structured, deterministic JSON payloads that directly control Unity animations, NavMesh pathfinding, inventory transfers, and dialogue UIs.

In Part 2, we implement a production C# parser that enforces JSON Function Calling and hooks directly into Unity Behavior Trees and state machines.


1. Defining the AI NPC Action Schema

To guarantee the LLM outputs valid JSON, we inject a strict JSON Schema into the System Prompt.

System Prompt Payload Example

JSON
{
  "system_instruction": "You are Sir Gareth, a veteran knight guard in a fantasy RPG. Respond to the player with dialogue, but ALSO decide your physical action in 3D space.",
  "json_schema_format": {
    "dialogue": "String (NPC spoken text)",
    "emotion": "Enum ['Neutral', 'Angry', 'Happy', 'Suspicious']",
    "target_action": "Enum ['Idle', 'WalkToPoint', 'AttackTarget', 'GiveItem']",
    "destination_tag": "String (e.g. 'TownGate', 'Blacksmith', 'Player')",
    "item_id": "String or null"
  }
}

2. Production C# Code: JSON Parser & Behavior Tree Driver

Below is a robust C# controller (AINPCBehaviorTreeDriver.cs) that parses structured JSON output and converts it into Unity NavMesh movement and animation triggers.

CSHARP
using System;
using UnityEngine;
using UnityEngine.AI;

/// <summary>
/// Production C# Driver for executing LLM-generated JSON actions inside Unity.
/// Connects LLM responses to NavMeshAgent pathfinding and Animator state triggers.
/// </summary>
public class AINPCBehaviorTreeDriver : MonoBehaviour
{
    [Header("Engine Component References")]
    [SerializeField] private NavMeshAgent agent;
    [SerializeField] private Animator animator;

    [Header("Waypoint References")]
    [SerializeField] private Transform townGateTransform;
    [SerializeField] private Transform blacksmithTransform;
    [SerializeField] private Transform playerTransform;

    [System.Serializable]
    public class NPCActionResponse
    {
        public string dialogue;
        public string emotion;
        public string target_action;
        public string destination_tag;
        public string item_id;
    }

    /// <summary>
    /// Parses the raw JSON response from the LLM and executes physical game actions.
    /// </summary>
    public void ProcessAIResponsePayload(string rawJson)
    {
        try
        {
            NPCActionResponse actionPayload = JsonUtility.FromJson<NPCActionResponse>(rawJson);
            Debug.Log($"[AI Action Decoded]: {actionPayload.target_action} -> {actionPayload.destination_tag}");

            // 1. Trigger Animation & Emotion State
            ApplyNPCEmotion(actionPayload.emotion);

            // 2. Drive Physical Movement & Behavior Tree Action
            ExecutePhysicalAction(actionPayload.target_action, actionPayload.destination_tag);
        }
        catch (Exception ex)
        {
            Debug.LogError($"[AI JSON Parsing Error]: Failed to parse payload. Error: {ex.Message}");
        }
    }

    private void ApplyNPCEmotion(string emotion)
    {
        if (animator == null) return;

        switch (emotion.ToLower())
        {
            case "angry":
                animator.SetTrigger("TriggerAngry");
                break;
            case "happy":
                animator.SetTrigger("TriggerHappy");
                break;
            default:
                animator.SetTrigger("TriggerIdle");
                break;
        }
    }

    private void ExecutePhysicalAction(string action, string destinationTag)
    {
        if (agent == null) return;

        if (action == "WalkToPoint")
        {
            Transform targetDestination = ResolveDestinationTransform(destinationTag);
            if (targetDestination != null)
            {
                agent.SetDestination(targetDestination.position);
                if (animator != null) animator.SetBool("IsWalking", true);
            }
        }
        else if (action == "Idle")
        {
            agent.ResetPath();
            if (animator != null) animator.SetBool("IsWalking", false);
        }
    }

    private Transform ResolveDestinationTransform(string tag)
    {
        switch (tag.ToLower())
        {
            case "towngate": return townGateTransform;
            case "blacksmith": return blacksmithTransform;
            case "player": return playerTransform;
            default: return null;
        }
    }
}

3. What's Coming in Part 3

Now that our AI NPC can think (Part 1) and act physically in 3D space (Part 2), the final step is giving the AI a realistic voice.

In Part 3 of this masterclass, we cover:

  • Low-Latency Text-To-Speech (TTS) Voice Streaming: Integrating ElevenLabs / OpenAI Audio APIs with Unity AudioSource.
  • Zero-Allocation PCM Audio Buffering: Streaming 3D spatial voice chunks into Unity without memory spikes or audio stuttering.

šŸ‘‰ Read Part 3: Low-Latency Spatial Audio & Voice Streaming (TTS) →


šŸ’” Building a Custom AI Gameplay System?

Need help structuring JSON schemas, implementing robust AI behavior trees, or preventing invalid LLM outputs in Unity?

  • AI Behavior Tree Architecture: Designing deterministic state machine handlers for LLM outputs.
  • Unity Engine Integration: Zero-allocation JSON parsing and NavMesh pathfinding optimization.

šŸ‘‰ Book an AI Gameplay Engineering Consultation or reach out directly to discuss your project.


šŸŽ® Shipped Projects & Official Store Profiles

Explore commercial titles and technical systems built with Unity across official stores:


Planning an AI-powered title? Check out our AI Gameplay Systems Services or explore our 2026 Mobile Game Development Cost Guide.

Share this article

Looking to build a production-ready game?

See how I built Bird Sort Mania in 20 days using AI, or check out my full Mobile Games Portfolio to see my shipped titles on Android and iOS.

Join 5,000+ Game Developers

Get weekly insights on Unity performance optimization, AI gameplay architectures, and robust system design. No spam, just deep technical breakdowns.

Unsubscribe at any time. Your data is never shared.

Recommended Reading

More articles in AI Gameplay