GEMINI LABEN
NANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定ですNANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定です
記事一覧/API / SDK
API / SDK/2026-03-19中級

Unity × Gemini API でNPCに知性を与える方法 — AIドリブンゲーム開発入門

Unity のゲーム開発に Gemini API を組み込んで、NPCに自然な会話能力や状況判断力を与える方法を解説。セットアップからプロンプト設計、レスポンス処理まで実践的に紹介します。

Unity2Gemini API191NPC2AI10ゲーム開発C#2会話AI

RPG で村人に話しかけて、三度目に同じ台詞が返ってきた瞬間、世界が急に書き割りに見えてしまう。会話の分岐を何本用意しても、この底が抜ける感覚はなかなか消えません。

NPC がプレイヤーの問いに自分の言葉で答え、ゲーム世界の状況を踏まえ、性格を保ったまま話す。Gemini API を Unity に繋ぐと、そこに手が届きます。実際に会話できる NPC を組み上げるまでを追いかけます。

Gemini API の基礎

Gemini は Google が開発した生成 AI モデルです。会話型の AI との大きな違いは、以下の点です:

  • 高速な応答:レイテンシーが低く、ゲーム内での使用に適している
  • マルチモーダル対応:テキストだけでなく、画像入力もサポート(NPCの顔表情認識など拡張可能)
  • コスト効率:API の呼び出しが比較的低コスト
  • キャラクター性の保持:システムプロンプトにより、NPC のキャラクター設定を一貫性を持って表現可能

Gemini API は REST API として提供されており、Unity の UnityWebRequest で簡単に統合できます。

セットアップ:Gemini API の導入

ステップ 1: Google Cloud コンソールでプロジェクト設定

  1. Google Cloud Console にアクセス
  2. 新しいプロジェクトを作成(例:「UnityGameAI」)
  3. Gemini API を有効化
  4. API キーを生成(認証情報 → API キー → 新規作成)

ステップ 2: Unity プロジェクトで API キーを安全に管理

API キーは絶対に GitHub や公開リポジトリに含めてはいけません。Unity では ScriptableObject を使うか、環境変数で管理します:

using UnityEngine;
using System;
 
[CreateAssetMenu(menuName = "AI/Gemini Config")]
public class GeminiConfig : ScriptableObject
{
    [SerializeField]
    private string apiKey;
 
    public string ApiKey => apiKey;
}

セキュリティ重要事項:本番環境では、ゲーム内で API キーを直接保持するのではなく、バックエンドサーバーを経由して API を呼び出すようにしてください。

ステップ 3: Gemini API クライアントの実装

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using System.Text;
using Newtonsoft.Json;
 
public class GeminiAPIClient : MonoBehaviour
{
    [SerializeField]
    private GeminiConfig config;
 
    private const string API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent";
 
    [System.Serializable]
    public class GeminiRequest
    {
        public Content[] contents;
    }
 
    [System.Serializable]
    public class Content
    {
        public Role role;
        public Part[] parts;
    }
 
    [System.Serializable]
    public class Part
    {
        public string text;
    }
 
    [System.Serializable]
    public enum Role
    {
        user,
        model
    }
 
    [System.Serializable]
    public class GeminiResponse
    {
        public Candidate[] candidates;
    }
 
    [System.Serializable]
    public class Candidate
    {
        public Content content;
    }
 
    public IEnumerator SendMessage(string userMessage, System.Action<string> onResponse)
    {
        var request = new GeminiRequest
        {
            contents = new[]
            {
                new Content
                {
                    role = Role.user,
                    parts = new[] { new Part { text = userMessage } }
                }
            }
        };
 
        string jsonData = JsonConvert.SerializeObject(request);
        byte[] postData = Encoding.UTF8.GetBytes(jsonData);
 
        string url = $"{API_URL}?key={config.ApiKey}";
        var webRequest = new UnityWebRequest(url, "POST");
        webRequest.uploadHandler = new UploadHandlerRaw(postData);
        webRequest.downloadHandler = new DownloadHandlerBuffer();
        webRequest.SetRequestHeader("Content-Type", "application/json");
 
        yield return webRequest.SendWebRequest();
 
        if (webRequest.result == UnityWebRequest.Result.Success)
        {
            var response = JsonConvert.DeserializeObject<GeminiResponse>(webRequest.downloadHandler.text);
            string responseText = response.candidates[0].content.parts[0].text;
            onResponse?.Invoke(responseText);
        }
        else
        {
            Debug.LogError($"Gemini API Error: {webRequest.error}");
            onResponse?.Invoke("エラーが発生しました");
        }
    }
}

NPC 会話システムの実装

ステップ 1: NPC キャラクターベースクラスの設計

using UnityEngine;
using System.Collections.Generic;
 
public class NPCCharacter : MonoBehaviour
{
    [SerializeField]
    private string npcName;
 
    [SerializeField]
    private string characterPrompt;  // キャラクター設定
 
    [SerializeField]
    private GeminiAPIClient apiClient;
 
    [SerializeField]
    private GameObject dialogueUI;  // UI パネル
 
    private List<(string role, string message)> conversationHistory;
 
    private void Start()
    {
        conversationHistory = new List<(string, string)>();
    }
 
    public void StartConversation()
    {
        conversationHistory.Clear();
        dialogueUI.SetActive(true);
    }
 
    public void SendMessage(string userMessage)
    {
        // 会話履歴に追加
        conversationHistory.Add(("user", userMessage));
 
        // API 呼び出し用のコンテキスト構築
        string contextMessage = BuildConversationContext(userMessage);
 
        StartCoroutine(apiClient.SendMessage(contextMessage, OnResponseReceived));
    }
 
    private string BuildConversationContext(string userMessage)
    {
        // キャラクター設定 + 会話履歴 + 新しいメッセージを組み立て
        var sb = new System.Text.StringBuilder();
        sb.AppendLine(characterPrompt);
        sb.AppendLine("\n【会話履歴】");
 
        foreach (var (role, message) in conversationHistory)
        {
            sb.AppendLine($"{(role == "user" ? "プレイヤー" : npcName)}{message}");
        }
 
        return sb.ToString();
    }
 
    private void OnResponseReceived(string response)
    {
        // NPC の応答を会話履歴に追加
        conversationHistory.Add(("npc", response));
 
        // UI に表示
        DisplayDialogue(response);
    }
 
    private void DisplayDialogue(string text)
    {
        // DialogueUI スクリプトで表示処理を実行
        var dialoguePanel = dialogueUI.GetComponent<DialoguePanel>();
        dialoguePanel.ShowMessage(npcName, text);
    }
}

ステップ 2: キャラクター設定(システムプロンプト)の設計

Gemini API の力を最大限に発揮するには、詳細で一貫性のあるキャラクター設定が重要です:

あなたは「フロディア」という老賢者の魔法使いです。
年齢は150歳で、東の塔に住んでいます。
性格:穏やか、思慮深い、時々ユーモアを交える。
口癖:「ふむふむ」「わかるかね」

このファンタジー世界では:
- 魔法は四大元素(火・水・風・土)で構成される
- 人間とエルフは共存しているが、時々緊張がある
- 黒い魔法は禁止されている

会話のルール:
1. 常に日本語で、キャラクターらしく話してください
2. ゲーム世界の知識を使って応答してください
3. プレイヤーの質問に丁寧に答えてください
4. 長すぎない応答(1~3文程度)をしてください

例)
プレイヤー:「炎の魔法を習いたいのですが」
フロディア:「ふむふむ、良い心がけじゃな。炎の魔法は火元素の力を扱うもの。まずは基礎を学ぶ必要があるわかるかね?わしが教えてやろう。」

このような詳細なプロンプトを設定することで、NPC が単なる情報応答機ではなく、ゲーム世界の登場人物として機能するようになります。

ステップ 3: 会話履歴の管理と最適化

長い会話になると、API に送信するトークン数が増加し、コストと レイテンシーが増加します。会話履歴を適切に管理することが重要です:

private const int MAX_HISTORY_PAIRS = 5;  // 最大 5 ターン分保持
 
private string BuildConversationContext(string userMessage)
{
    var sb = new System.Text.StringBuilder();
    sb.AppendLine(characterPrompt);
    sb.AppendLine("\n【会話履歴】");
 
    // 古い履歴を削除し、最新の N 個のみ保持
    int startIndex = Mathf.Max(0, conversationHistory.Count - MAX_HISTORY_PAIRS * 2);
 
    for (int i = startIndex; i < conversationHistory.Count; i++)
    {
        var (role, message) = conversationHistory[i];
        sb.AppendLine($"{(role == "user" ? "プレイヤー" : npcName)}{message}");
    }
 
    sb.AppendLine($"プレイヤー:{userMessage}");
 
    return sb.ToString();
}

実践的な活用例

例 1: 店主 NPC による動的会話

public class MerchantNPC : NPCCharacter
{
    [SerializeField]
    private List<ItemData> inventory;
 
    protected override string BuildCharacterPrompt()
    {
        var sb = new System.Text.StringBuilder();
        sb.AppendLine("あなたは「マルコ」という商人です。");
        sb.AppendLine("性格:商売好き、机敏、時々ぼったくりを試みる");
        sb.AppendLine("\n現在の在庫:");
 
        foreach (var item in inventory)
        {
            sb.AppendLine($"- {item.name}{item.price} ゴールド");
        }
 
        sb.AppendLine("\nプレイヤーの質問に応じて、商品を勧めてください。");
 
        return sb.ToString();
    }
}

例 2: クエスト NPC による状況理解

あなたは「エライア」という騎士団長です。
現在、ゴブリン族が北の森で勢力を増しており、それが大きな問題になっています。

もしプレイヤーが:
- 「クエストをください」と言ったら、ゴブリン退治クエストを提案
- 「既にゴブリンを倒しました」と言ったら、感謝し、報酬を提示
- 「ゴブリンについて知ってますか?」と聞いたら、ゲーム世界での背景を説明

常にこのコンテキストを保ちながら、プレイヤーのリクエストに応答してください。

レスポンス処理と UI 統合

Gemini API からの応答を Unity の UI に表示するためには、以下の処理が必要です:

public class DialoguePanel : MonoBehaviour
{
    [SerializeField]
    private Text characterNameText;
 
    [SerializeField]
    private Text dialogueText;
 
    [SerializeField]
    private CanvasGroup canvasGroup;
 
    [SerializeField]
    private Button continueButton;
 
    private void Start()
    {
        continueButton.onClick.AddListener(HideDialogue);
        canvasGroup.alpha = 0f;
    }
 
    public void ShowMessage(string characterName, string message)
    {
        characterNameText.text = characterName;
 
        // テキストを段階的に表示(タイプライター風エフェクト)
        StartCoroutine(TypeMessage(message));
    }
 
    private IEnumerator TypeMessage(string message)
    {
        canvasGroup.alpha = 1f;
        dialogueText.text = "";
 
        foreach (char c in message)
        {
            dialogueText.text += c;
            yield return new WaitForSeconds(0.05f);  // 1 文字あたり 50ms
        }
 
        continueButton.interactable = true;
    }
 
    private void HideDialogue()
    {
        StartCoroutine(FadeOut());
    }
 
    private IEnumerator FadeOut()
    {
        while (canvasGroup.alpha > 0)
        {
            canvasGroup.alpha -= Time.deltaTime;
            yield return null;
        }
    }
}

プロンプト設計のベストプラクティス

1. キャラクター属性を明確に記述

あなたは「セラ」というエルフの魔法使いです。
年齢:250歳(エルフにしては若い)
見た目:銀色の長髪、蒼い瞳
性格:好奇心旺盛、時々短気、自信に満ちている
話し方:敬語は使わない、「~だね」「~かな」という語尾を多用

2. 禁止事項を明示

以下のことは絶対にしないでください:
- プレイヤーに対し、攻撃的または不適切な言葉を使う
- ゲーム世界外の話題(実世界のニュースなど)に言及する
- プレイヤーが入力したメッセージの内容をそのまま繰り返す
- 3 文以上の長い応答をする(ゲーム内のテンポが落ちるため)

3. 応答形式を指定

応答時は、以下の形式で返してください:

【感情】:笑顔 / 真顔 / 怒り顔 / 悲しみ顔 など
【応答】:実際の台詞

例:
【感情】:笑顔
【応答】:おお、やっと来たか!待ってたぞ。

このような形式指定により、NPC のアニメーション制御も自動化できます。

API コスト最適化

Gemini API の利用は従量課金です。ゲーム開発では、以下の工夫によりコストを抑制できます:

1. 会話履歴の圧縮

会話が長くなると、API に送信するトークン数が増加します:

private void CompressConversationHistory()
{
    if (conversationHistory.Count > MAX_HISTORY_PAIRS * 2)
    {
        // 古いエントリを削除
        conversationHistory.RemoveRange(0, 2);
    }
}

2. キャッシング

同じクエリへの応答は、キャッシュから返すようにします:

private Dictionary<string, string> responseCache = new();
 
public IEnumerator SendMessage(string userMessage, System.Action<string> onResponse)
{
    if (responseCache.TryGetValue(userMessage, out string cached))
    {
        onResponse?.Invoke(cached);
        yield break;
    }
 
    // API 呼び出し...
}

3. ローカルフォールバック

インターネット接続がない場合や API が利用不可の場合のため、シンプルな応答テンプレートを用意:

private string GetFallbackResponse(string userMessage)
{
    if (userMessage.Contains("こんにちは"))
        return "やあ、元気にしてるか?";
    else if (userMessage.Contains("クエスト"))
        return "クエストについてなら、掲示板を確認してくれ。";
    else
        return "そうだね…(何か考えている)";
}

マルチモーダル対応:顔表情認識への応用

Gemini API はテキストだけでなく、画像入力もサポートしています。例えば、NPC の顔をゲーム内で生成し、プレイヤーの表情に反応させることも可能です:

public IEnumerator SendMessageWithImage(Texture2D image, string userMessage, System.Action<string> onResponse)
{
    // 画像を Base64 にエンコード
    byte[] imageData = image.EncodeToPNG();
    string base64Image = System.Convert.ToBase64String(imageData);
 
    // API リクエストに画像を含める
    // (詳細な実装は省略)
}

これによって、プレイヤーの表情とゲーム状況から、NPC が自動的に最適な応答を生成することが可能です。

ネットワークとセキュリティの考慮事項

1. 通信の暗号化

// HTTPS を使用(UnityWebRequest は自動的に HTTPS をサポート)
webRequest.url = "https://generativelanguage.googleapis.com/...";

2. API キーの保護

本番環境では、クライアント側で API キーを直接保持しないようにします:

// ❌ 危険
string apiKey = "直接埋め込まれたキー";
 
// ✅ 推奨
// バックエンドサーバーを経由してリクエスト
StartCoroutine(CallBackendNPCAPI(userMessage, onResponse));

トラブルシューティング

よくある問題と解決策

Q: API の応答が遅い

  • A: 会話履歴を制限する、キャッシング機能を導入する

Q: NPC の応答がキャラクターと合致していない

  • A: システムプロンプトをより詳細に、具体例を多く含めて修正

Q: API キーが漏洩した

  • A: Google Cloud Console で即座に無効化し、新しいキーを生成

まとめ

Gemini API を Unity に統合することで、以下のメリットが実現します:

  1. 動的な NPC 会話:スクリプトされた台詞の枠を超えた自由な会話が可能
  2. ゲーム世界への没入感向上:NPC がゲーム世界の文脈を理解した応答をする
  3. 開発効率の向上:膨大な会話分岐をスクリプト化する必要がなくなる
  4. プレイヤーの選択肢拡大:任意の質問に対応できるため、プレイヤーがより自由に行動できる
  5. リプレイ価値の向上:毎回異なる会話内容により、ゲーム体験が多様化

これは、ゲーム開発における AI 活用の一つの典型例です。Gemini API を上手く活用することで、プレイヤーにとって本当に「知性のある NPC」との交流がゲーム内で実現できるのです。


本記事で紹介した基本的なセットアップと簡単な NPC 会話の実装に加えて、本記事の続きとなるプレミアム記事では、マルチモーダル AI を用いた NPC 顔表情の自動生成、ストリーミング応答による高速な対話実装、複雑なキャラクター会話フローの完全コード集、およびプロダクション環境でのスケーリング戦略を詳しく解説しています。

シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

API / SDK2026-03-19
Unity × Gemini マルチモーダル AI 実装 完全コード集【上級編】
Unity に Gemini API のマルチモーダル機能(テキスト+画像+音声)を統合する完全実装ガイド。ストリーミング応答、画像認識NPC、音声対話システム、コンテキスト管理まで本番レベルのC#コードを公開。
API / SDK2026-07-09
Google Sheets API × Gemini API でつくるデータ処理パイプライン — Apps Script 不要の Python 自動化
サービスアカウントを使った Google Sheets API の認証から、Gemini API でのデータ分析・分類・要約まで、Python だけで完結するスプレッドシート AI 自動化パイプラインを解説します。
API / SDK2026-03-14
Gemini Code Execution API — AIにコードを書かせて実行する
Gemini Code Execution APIの使い方。AIが生成したコードを安全に実行し、数学計算、データ処理、複雑な分析をAIに任せる方法を解説します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →