4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unity × OllamaでローカルLLMを動かす!軽量モデルでAI NPC実装

Posted at

はじめに

この記事は Life is Tech ! Advent Calendar 2025 5日目の記事です。

こんにちは!Life is Tech!で Unity・AIメンターをしています!ピナです🍍
大学では、AIのチャットボットの研究をしています!普段はPythonを使ってチャットボットの実装をしています。今回はOllamaという大規模言語モデル(これからLLMと書きます。)をローカル環境で簡単に実行できるツールを紹介します。またOllamaをUnityの結びつける方法も記載します。

最近ではAPIなどを使うと簡単にLLMを実装できますが、お金を使ったり、ログインが必要だったりと少し手間が多い印象です。もっと簡単に試しにどんなことができるのかを知りたい方にこの記事を書いてます
主に対象はUnityを少しでも触ったことがある方です!

前提

Unity 2022.3.62f2

実装

Ollamaの導入

使っているOSに合わせて、以下の URL からインストーラーをダウンロードし、インストールしてください。

macOS: https://ollama.com/download
Windows: https://ollama.com/download/windows
Linux: https://ollama.com/download/linux

image.png

ダウンロード後、MacならdmgファイルをWindowsならexeファイルを実行。Ollamaを開きます。
Macならターミナル、Windowsならコマンドプロンプト/PowerShellを開き、ollama コマンドが実行できることを確認してください。

ollama --version

以下のようにバージョンが出ればOKです。(バージョンはダウンロード時期によって変わる可能性がありますが問題ないです。)

 ~ % ollama --version
ollama version is 0.13.1

Ollamaでモデルをダウンロード

今回はお試しということで軽量のモデルphi3を使います。そのほかにもモデル(GoogleのGemma、MetaのLlamaなど様々ありますが、ぜひ何のモデルを使うかは自分で決めてみてください。)
phi3とは、Microsoftからリリースされたモデルで、とても軽量で効率的なのが特徴です。

以下を実行。

ollama pull phi3

以下のようにsuccessと出たらダウンロードできています。

 ~ % ollama pull phi3
pulling manifest 
pulling fd7b6731c33c: 100% ▕█████████████████████████████▏ 9.1 GB                         
pulling 32695b892af8: 100% ▕█████████████████████████████▏  275 B                         
pulling fa8235e5b48f: 100% ▕█████████████████████████████▏ 1.1 KB                         
pulling 45a1c652dddc: 100% ▕█████████████████████████████▏   82 B                         
pulling f5d6f49c6477: 100% ▕█████████████████████████████▏  486 B                         
verifying sha256 digest 
writing manifest 
success 

ダウンロードが終わると、ローカルで phi3 モデルが使えるようになります。
(ollama run phi3を実行すると、phi3モデルで会話することができます。)

通常はOllamaを起動すると、バックグラウンドでサーバーが動きます。
なのでUnityから http://localhost:11434 というアドレスに問い合わせるだけでモデルを動かすことができます。
(ニュアンスの意味としてはlocalhost は「自分のPC」、11434 はOllamaを識別する番号と思ってください。)

Unityの画面作成

今回は、アドベントカレンダーということでサンタさんと話せるような画面を作ってみます。(あくまで例なので、自分の作りたいように作ってみてください。)
Unityの画面は以下のようにしました。
image.png

必要なオブジェクト

  • Canvas
  • InputField
    プレイヤーが質問を入力する欄
  • Button
    「送信」ボタンとして使う
  • Text
    サンタが返事するテキスト

スクリプトの作成

ファイル名:OllamaChatNPC.cs(例)

役割:

  • プレイヤーの入力を受け取る
  • Ollama に質問を送る
  • 返事を NPC の吹き出しに表示する
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

// 送るデータ(Ollama /api/generate 用)
[System.Serializable]
public class GenerateRequest
{
    public string model;
    public string system;
    public string prompt;
    public bool stream; // false にすると返事が一括で返ってきて扱いやすい
}

// 受け取るデータ(Ollama の返答JSONのうち必要部分だけ)
[System.Serializable]
public class GenerateResponse
{
    public string response;
}

public class OllamaChatNPC : MonoBehaviour
{
    [Header("UI")]
    [SerializeField] private InputField inputField;
    [SerializeField] private Text npcText;

    private const string URL = "http://localhost:11434/api/generate";
    private const string MODEL = "phi3";

    // システムプロンプト:NPCのキャラクター設定
    [SerializeField, TextArea]
    private string systemPrompt =
        "あなたはサンタです。明るく優しく、一言だけで返事してください。20文字以内で答えてください。サンタなような口調で答えてください。";


    // ボタンから呼ぶ想定
    public void Send()
    {
        var user = inputField.text;
        if (string.IsNullOrWhiteSpace(user)) return;

        npcText.text = "考え中…";
        StartCoroutine(Generate(user));
    }

    private IEnumerator Generate(string userMessage)
    {
        // 1) Ollama に送る JSON を作る
        var reqData = new GenerateRequest
        {
            model = MODEL,
            system = systemPrompt,
            prompt = userMessage,
            stream = false
        };

        var json = JsonUtility.ToJson(reqData);

        // 2) HTTP POST で localhost の Ollama に送る
        using var req = new UnityWebRequest(URL, "POST");
        req.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(json));
        req.downloadHandler = new DownloadHandlerBuffer();
        req.SetRequestHeader("Content-Type", "application/json");

        // 3) 送信して返事を待つ
        yield return req.SendWebRequest();

        // 4) 失敗時
        if (req.result != UnityWebRequest.Result.Success)
        {
            npcText.text = $"通信エラー: {req.error}";
            yield break;
        }

        // 5) 成功時:JSON から response だけ取り出す
        var resJson = req.downloadHandler.text;
        var resData = JsonUtility.FromJson<GenerateResponse>(resJson);

        npcText.text = string.IsNullOrEmpty(resData?.response)
            ? "うまく返事を受け取れませんでした。"
            : resData.response;

        // お好みで入力欄クリア
        inputField.text = "";
    }
}

また中でも、systemPromptという変数の中では、
「サンタとして一言で返事してね」というルール(システムプロンプト)を付ける。

システムプロンプト(systemPrompt)が重要な理由
ゲームに入れる場合、「NPC の性格や口調を毎回同じにしたい」という要求が出ます。
それを一番簡単に実現できるのが システムプロンプトの固定です。
(ですが、AIが完全に万能ってわけではないのでシステムプロンプト通り行くとは限りません。モデルの性能が良いほど、いい回答は出やすくなりますが。)

UnityとC#の紐付け

  • OllamaChatNPC スクリプトをアタッチを任意のオブジェクトにアタッチ
  • Inspector でフィールドにオブジェクトをセット
    • InputField:シーンの入力欄
    • npcText:NPC の吹き出しテキストオブジェクト
  • 「送信」ボタンを選択
  • OnClick イベントにOllamaChatNPCs スクリプトがアタッチされたオブジェクトをドラッグ&ドロップ
  • OllamaChatNPC.Send を選択

実行してみる

入力欄に「メリークリスマス!プレゼントは何が良いかな?」と入力

image.png

image.png

ちょっと文章が変だけど、もしかしたらモデルを変えたりすると良くなりそう!

※PCの性能によっては、返事が返ってくるまで数秒〜数十分かかる場合があります。「考え中…」のまま止まってしまったように見えても、裏では一生懸命計算しているので少し待ってあげてください。

注意点

あくまでOllamaはローカルの実行が前提なのでWebGLなどのリリースにそのまま移植は難しいです。リリースなどを目的とする場合はOpen AIなどのAPIを使ってのリリースを目指すと良いでしょう。
また、AIは万能ではなく確率的に文字を作っているだけに過ぎないので、システムプロンプト通りの回答にならなかったり、嘘をつく可能性(ハルシネーション)が含まれているので絶対の信頼をおくのではなく、技術を楽しむぐらいの立ち位置だと良いと思います。

感想

 Ollamaを初めて使ったのですが、こんなにも簡単にLLMを使うことができるの単純にすごい!いろんなモデルもあるから、それぞれのモデルの比較検討とかでも使えそうって思ったり!
 ゲームの方は今のところはNPCに言葉を話してもらうだが、アイデア次第ではもっと自由度高くできそう!AIに特定の言葉を言わせるゲームとか?
LLM ❌ ゲーム で何か作ってみたいなって思いました!

読んでくださり、ありがとうございました!

参考記事

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?