Unity 6 Play Modeテスト環境構築と実行方法

2025年5月8日

Unity の Play Mode テスト(Play Mode Test)は、実際にシーンを実行した状態でゲーム動作や物理演算、コルーチン、UI の挙動などを自動で検証できる強力なツールです。本記事では、Unity 6 の Test Runner を用いて、Play Mode テストを一から構築し、コインをキューブの上に初期配置して重力で落下させ、CoinCollector で回収を検証するサンプルをステップバイステップにご紹介します


0. 本記事で扱うテストについて

  • テスト対象:CoinCollector コンポーネントの OnTriggerEnter()
  • テスト内容
    1. コイン(Sphere)をキューブ(Cube、地面代わり)の上に初期配置し、重力で落下
    2. コインがプレイヤー(Sphere、CoinCollector)のトリガーに入ったら score が 1 増え、コインは非アクティブ化

このサンプルで、Play Mode テスト特有の [UnityTest]/[UnitySetUp]、コルーチンによる待機(yield return new WaitForFixedUpdate/yield return new WaitForSeconds)、そして物理演算と衝突検証の流れを学べます。


1. Play Mode Test Runner とは

Test Runner は Unity 上で Edit Mode(エディタ内単体テスト)と Play Mode(実際の実行状態テスト)の両方をサポートするテストフレームワークです。

  • Edit Mode テスト:スクリプトのみの単体検証向け
  • Play Mode テスト:シーン実行中の動作、物理やレンダリング、コルーチンを含む統合的なテスト向け

Play Mode テストはシーンをロードし、MonoBehaviour やコルーチンをそのまま実行するため、ゲームロジック全体の動作確認に最適です。


2. 初期設定と環境構築

2.1. プロジェクトの準備

  1. Unity Hub を起動し、新規プロジェクト を作成
  2. テンプレートは、Universal 3D
  3. プロジェクト名例:「PlayModeDropCoinSample」

2.2. Test Runner ウィンドウの開き方

  1. Unity エディタのトップメニューからWindow → General → Test Runner を選択
  2. フローティングウィンドウで Test Runner が表示される

3. テストコード保存用フォルダとテストスクリプトの作成

3.1. テストコード保存用フォルダの作成

  1. Test Runner ウィンドウ上部の PlayMode タブをクリック
  2. Create a new Test Assembly Folder in the active path ボタンをクリック
  3. Assets/Tests フォルダが生成される

ポイント
Play Mode用のアセンブリ定義が自動的に作成され、PlayMode タイプに設定されます。

アセンブリ定義(Assembly Definition)とは?

Unity における「アセンブリ定義ファイル」(.asmdef)は、スクリプトをコンパイル単位(アセンブリ)に分割・管理するための設定ファイルです。通常、Unity はプロジェクト内のスクリプトを自動的にいくつかの標準アセンブリ(例:Assembly-CSharp.dll)にまとめてコンパイルしますが、.asmdef を置くことで、任意のフォルダー以下を独自のアセンブリとして切り出すことができます。


Unity における主な役割とメリット

  1. コンパイル時間の短縮
    • 大規模プロジェクトでは、全スクリプトを毎回まとめて再コンパイルすると時間がかかります。
    • アセンブリ定義でモジュール化すると、変更箇所があるアセンブリのみが再コンパイルされるため、ビルド時間が大幅に削減されます。
  2. 依存関係の明示
    • あるアセンブリが別のアセンブリを参照する場合、.asmdef 内で依存関係(References)を明示的に設定します。
    • これにより、コードの構造が見通しやすくなり、無駄な参照や循環参照を防ぎます。
  3. 名前空間・アクセス制御
    • 切り出したアセンブリごとにアクセス可能な API を制限でき、不要な内部実装の露出を抑えられます。
  4. プラットフォーム/ビルド設定の分離
    • 各アセンブリに対し、対象プラットフォーム(Editor、Standalone、iOS、Android など)を個別に設定可能。
    • テスト用アセンブリは Editor のみで動かす、ランタイム用はプレイヤー環境でも含める、などの制御ができます。

Test Runner とアセンブリ定義の関係

Unity の Test Runner(Edit Mode/Play Mode テスト)では、テストコードを専用のアセンブリとして分離して管理することが推奨されています。これには以下の手順で .asmdef を利用します。

  1. テスト用フォルダーにアセンブリ定義を作成
    • 例:Assets/Tests/EditMode/Assembly Definition に EditModeTests.asmdef を置く。
    • Inspector で “Test Assemblies" → “Editor" を有効化し、テストランナーから参照できるように設定。
  2. 参照設定
    • テスト対象のランタイムアセンブリ(例:Assembly-CSharp)を References に追加。
    • 必要に応じて、他のパッケージやアセンブリ定義を参照設定します。
  3. Play Mode テスト用アセンブリ
    • Assets/Tests/PlayMode/PlayModeTests.asmdef を作成し、同様に Play Mode テスト用の設定を行います。
    • Platforms で “Editor" のほかに “Standalone" などを含めることで、プレイヤー環境下の API をテストできます。
// 例: EditModeTests.asmdef の中身(一部抜粋)
{
  "name": "EditModeTests",
  "references": [
    "Assembly-CSharp",           // ランタイム用アセンブリ
    "UnityEditor",               // Editor API が必要な場合
    "UnityEngine.TestRunner"     // Test Runner ライブラリ
  ],
  "includePlatforms": [
    "Editor"
  ],
  "allowUnsafeCode": false,
  "overrideReferences": false
}

まとめ

  • アセンブリ定義(.asmdef) は、スクリプトをモジュール化してコンパイル単位を管理するファイル。
  • 適切に分割することで ビルド速度が速く依存関係が見えやすくプラットフォーム制御 も行いやすくなる。
  • Test Runner を使う際は、Edit Mode/Play Mode ごとにテスト用アセンブリを定義し、対象アセンブリを References に設定することで、安定したテスト環境を構築できる。

これらを活用して、プロジェクト構造を整理しながら効率的にユニットテスト・統合テストを進めてみてください。

3.2. テストスクリプトの作成

  1. Assets/Tests フォルダ内のTestsアセンプリを選択
  1. Test Runner 内の Create a new Test Script in the active path をクリック
  2. 自動生成されたスクリプトの名前を DropCoinPlayModeTests  に変更

3.3. 自動生成サンプルスクリプトの実行

  1. PlayMode タブで Run All をクリック
  2. 何もしないサンプルなので、全テストが  成功することを確認

補足
この時点ではテストメソッドが空なので、パスするだけです。

3.4. サンプルスクリプトの編集

以下のように書き換えます。

  • プレイヤーに CoinCollector とトリガー化した SphereCollider を付与
  • コインに Coin マーカーコンポーネントと Rigidbody(重力有効)を付与
  • コルーチンで落下を待ち、Assert.That で検証します。
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;

public class DropCoinPlayModeTests
{
    GameObject player;
    CoinCollector collector;
    GameObject coin;

    [UnitySetUp]
    public IEnumerator SetUp()
    {
        // — プレイヤーを用意 —
        player = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        var sc = player.GetComponent<SphereCollider>();
        sc.isTrigger = true;
        collector = player.AddComponent<CoinCollector>();

        // — キューブ(地面役)を配置 —
        var ground = GameObject.CreatePrimitive(PrimitiveType.Cube);
        ground.transform.localScale = new Vector3(3f, 1f, 3f);
        ground.transform.position = Vector3.zero;
        ground.GetComponent<BoxCollider>().isTrigger = false;

        // — コインをプレイヤーの真上に配置して重力落下させる —
        coin = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        coin.AddComponent<Coin>();             // マーカーコンポーネント
        var rb = coin.AddComponent<Rigidbody>(); // useGravity=true
        // 初期位置:プレイヤーの y + 半径 + マージン
        player.transform.position = new Vector3(0f, 0.5f, 0f);
        coin.transform.position   = player.transform.position + Vector3.up * 2f;

        // 物理エンジンへの登録待ち
        yield return new WaitForFixedUpdate();
    }

    [UnityTest]
    public IEnumerator DropCoin_TriggersCollection()
    {
        // 初期状態確認
        Assert.That(collector.score, Is.Zero,
            "初期状態で score は 0 であるべきです。");
        Assert.That(coin.activeSelf, Is.True,
            "初期状態でコインはアクティブであるべきです。");

        // 落下を待つ(十分余裕を持って 1 秒)
        yield return new WaitForSeconds(1f);

        // 衝突後の検証
        Assert.That(collector.score, Is.EqualTo(1),
            "コインが落下してプレイヤーに当たると score が 1 増えるはずです。");
        Assert.That(coin.activeSelf, Is.False,
            "コインは回収後に非アクティブ化されているはずです。");
    }
}

4. テスト対象コードの作成

4.1. Scripts フォルダを作成

  1. Project ウィンドウで Assets を右クリック
  2. Create → Folder で Scripts フォルダを作成

4.2. テスト対象スクリプトの作成

  1. Scripts フォルダを右クリック
  2. Create → MonoBehaviour Script を選択し、以下の 2 ファイルを作成します

Coin.cs

using UnityEngine;

/// <summary>
/// コインであることを示すマーカーコンポーネント
/// </summary>
public class Coin : MonoBehaviour { }

CoinCollector.cs

using UnityEngine;

public class CoinCollector : MonoBehaviour
{
    [Tooltip("回収したコインの数")]
    public int score;

    private void OnTriggerEnter(Collider other)
    {
        // Coin マーカーを持つ相手なら回収
        if (other.GetComponent<Coin>() != null)
        {
            score++;
            other.gameObject.SetActive(false);
        }
    }
}

5. アセンブリ定義ファイルの作成

5.1. テスト対象スクリプトのフォルダにアセンブリ定義を作成

  1. Project ウィンドウで Scripts フォルダを右クリック
  2. Create → Scripting → Assembly Definition を選択
  3. 生成された .asmdef の名前を GameScriptsAsm に変更

5.2. テスト用アセンブリ定義に依存関係を登録

  1. Project ウィンドウで Assets/Tests/Tests.asmdef をクリック
  2. Inspector の Assembly Definition References セクションで+ボタンをクリック
  3. GameScriptsAsm を選択し、Apply

+ボタンでアセンブリ定義参照の追加

点丸をクリックして選択ウィンドウを表示

一覧ウィンドウから、GameScriptsAsmを選択


6. Test Runner の実行

  1. Unity エディタで PlayMode タブを選択
  2. Test Runner ウィンドウの Run All をクリック
  3. テスト結果が以下のように表示されることを確認
    • 成功:DropCoin_TriggersCollection
    • ❌ 失敗:エラーがあれば該当テストを修正

7. 参考

  • [UnitySetUp] 属性
    Play Mode テスト開始前にコルーチンを使って初期化処理を挟むことができます。
  • [UnityTest] 属性
    戻り値を IEnumerator にして、yield return でフレームや条件待ちが可能です。
  • WaitForFixedUpdate / WaitForSeconds
    物理計算タイミングや時間経過の検証に活用できます。

以上で、Unity 6 の Play Mode テスト環境構築と「コイン収集テスト」のサンプル実行手順は完了です。シーンロードや UI 検証など、さらに複雑なテストにも本手順を応用してみてください。

Test,Unity

Posted by hidepon