AIで人間のシュミュレーション – 1

Unityで『The Sims』のように、人間が家の中で自律的に生活する(食事、睡眠、トイレ、娯楽など)シミュレーションを作るのは非常に面白いプロジェクトです。

これを実現するためには、単にアニメーションを再生するだけでなく、**「欲求(Needs)」「意思決定(Decision Making)」**のシステムを構築する必要があります。

以下に、開発に必要な主要な要素と具体的なステップをまとめました。


1. 核となる概念:欲求システム (Needs System)

人間が「次に何をするか」を決める動機づけが必要です。これを数値化して管理します。

  • パラメータ: キャラクターに以下のような変数を持たせます(0〜100の範囲など)。
    • Hunger (空腹度): 時間経過で減る。低いと「冷蔵庫」を探す。
    • Energy (体力): 活動すると減る。低いと「ベッド」を探す。
    • Bladder (尿意): 食事後に増える。高いと「トイレ」を探す。
    • Fun (娯楽): 時間経過で減る。低いと「テレビ」や「本」を探す。

これらが一定の閾値(しきい値)を超えたとき、キャラクターは行動を開始します。

2. 環境構築:スマートオブジェクト (Smart Objects)

キャラクターが「これは椅子だ」「これは冷蔵庫だ」と認識する仕組みが必要です。オブジェクト側に情報を埋め込みます。

  • アプローチ:家具のオブジェクトにスクリプト(例: InteractableObject)をアタッチし、以下のデータを持たせます。
    • Action Type: Sleep, Eat, Watch TV
    • Effect: Energy +50, Hunger +30
    • Interaction Point: キャラクターが立つべき位置、または座るべき位置。

キャラクターは「お腹が空いた」時、シーン内の全てのオブジェクトから「Hungerを回復できるもの」を検索し、一番近いもの(冷蔵庫など)に向かいます。

3. 移動システム:NavMesh (ナビメッシュ)

家の中を家具にぶつからずに歩くためには、Unity標準のNavMeshを使います。

  1. Bake: 家の床や壁をStatic(静的)に設定し、NavMeshをベイク(焼き付け)します。
  2. NavMesh Agent: キャラクターに NavMeshAgent コンポーネントをつけます。
  3. 移動: スクリプトで agent.SetDestination(target.position); とすれば、障害物を避けて自動で目的地へ向かいます。

4. 意思決定AI:何を使うべきか?

AIの構造にはいくつか種類がありますが、生活シミュレーションには以下のどちらかが適しています。

AIの種類特徴おすすめ度
FSM (ステートマシン)「待機→移動→食事」のように状態を切り替える。シンプルだが、行動が増えると複雑になる。初心者向け
Utility AI (ユーティリティAI)「今一番やりたいことは?」を点数化して決める。「少し眠いけど、すごくお腹が空いているから食べる」といった柔軟な判断が可能。推奨 (リアルな生活感が出る)
Behavior Tree (ビヘイビアツリー)階層構造で行動を管理する。アセットを使えば視覚的に作りやすい。中級者向け

実装のステップバイステップ

まずはシンプルな「お腹が空いたら冷蔵庫に行く」サイクルから作り始めましょう。

Step 1: キャラクターの作成 (C# Script)

HumanAI.cs というスクリプトを作成し、基本的な欲求を定義します。

C#

using UnityEngine;
using UnityEngine.AI;

public class HumanAI : MonoBehaviour {
    public float hunger = 100f;
    public float energy = 100f;
    
    NavMeshAgent agent;
    
    void Start() {
        agent = GetComponent<NavMeshAgent>();
    }

    void Update() {
        // 時間経過でパラメータを減らす
        hunger -= Time.deltaTime * 2.0f;
        energy -= Time.deltaTime * 0.5f;

        // 意思決定
        if (hunger < 30) {
            FindFood();
        }
        else if (energy < 20) {
            GoToSleep();
        }
    }

    void FindFood() {
        // シーン内の「Food」タグがついたオブジェクトを探して移動
        GameObject fridge = GameObject.FindGameObjectWithTag("Fridge");
        if (fridge != null) {
            agent.SetDestination(fridge.transform.position);
            // 注: 実際には到着したかどうかの判定が必要です
        }
    }
}

Step 2: 家具の設定

  1. Cubeなどで「冷蔵庫」「ベッド」を作る。
  2. 冷蔵庫に「Fridge」タグをつける。
  3. UnityのWindow > AI > Navigation からNavMeshをベイクする。

Step 3: アニメーションの連携

目的地に着いたら(agent.remainingDistance が一定以下になったら)、歩行アニメーションを止め、「食べる」や「寝る」アニメーションを再生します。


さらにクオリティを上げるために

  1. 時間帯 (Time of Day):夜になったら自動的に眠くなる、朝7時に起きる、といったリズムを作ると生活感が出ます。
  2. ランダム性:暇なとき(全ての欲求が満たされているとき)に、窓の外を眺めたり、部屋をうろうろする「Wander(徘徊)」状態を作ります。
  3. アセットの活用:AIを一から書くのは大変なため、視覚的にAIを作れるアセットの使用も検討してください。
    • Behavior Designer: 定番のビヘイビアツリー作成アセット。
    • NodeCanvas: 複雑なAIを作りやすい。

まずは、**「家の中にNavMeshを敷いて、空腹度が減ったら特定の場所へ移動する」**というプロトタイプから始めてみるのがおすすめです。