2
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?

コマンドラインからシーンをシミュレーションするときに学んだポイント

Last updated at Posted at 2024-12-23

PONOS Advent Calendar 2024の21日目の記事です。
昨日は@FW14Bさんの「業務用ゲーム機の修理から学んだこと」でした。

はじめに

最近、コマンドラインからゲーム本編中のシーンをシミュレーションする仕組みを構築しようとしました。
これまでバイナリビルドのシステムを開発したりはしていましたが、ゲーム本編の処理を実行する経験はなかったので、初歩的ではありますが個人的に学びを得られたポイントをまとめたいと思います。

コマンドからUnityエディタを立ち上げて特定メソッドを実行する

先述の通りバイナリビルドのシステムを開発した経験があったため、バッチモードでUnityを実行する方法は知っていましたが、Unityエディタを立ち上げる方法を経験したことがなかったので、改めてコマンドでUnityを起動する方法を調べながら実装しました。

公式のドキュメントは「Unity エディターのコマンドライン引数 - Unity マニュアル」にあります。

結論、バッチモードで実行する場合との差は-batchmodeを省くだけであり、Unityエディタを起動して目的のメソッドを実行することができました。-executeMethodはUnityエディタを起動した直後に実行する静的メソッドの名前を指定しています。

start_simulation.sh
"** 使用しているUnityのパス(/Unity.app/Contents/MacOS/Unity) **" \
    -projectPath "** Unityプロジェクトのルートディレクトリのパス **" \
    -executeMethod GameSimulator.Simulate
sh start_simulation.sh

Unityエディタのプレイモードを開始する / 終了する

シーンの挙動をシミュレーションしたい場合、Unityエディタでプレイモードを開始する必要があります。
また、目的のシミュレーションが終了したときにはプレイモードを終了する必要もあります。

これらのプレイモードの状態の切り替えには、EditorApplication.isPlayingの値を使用します。公式のドキュメントは「EditorApplication-isPlaying - Unity スクリプトリファレンス
」にあります。

使い方は簡単で、プレイモードを開始したいときにはtrueを、終了したいときにはfalseを設定するだけです。

// シミュレーションを開始するために、プレイモードを開始する。
EditorApplication.isPlaying = true;

// シミュレーションを終了するために、プレイモードを終了する。
EditorApplication.isPlaying = false;

シミュレーション中の情報を保持する

シミュレーションの進行中の情報を保存したい場合、Unityエディタの起動時に使用したstaticなメソッドやクラスに保持させたいと考えますが、前述のプレイモードの開始をしていると容易にstaticフィールドが初期化されてしまうため、情報を保持することができません。

シリアライズされた値は初期化されることがないため、EditorWindowを用意して情報をシリアライズ可能にしておくことで保持することも可能ですが、基本的にシミュレーション中は人が操作・監視しないことを想定しているため、人の目に触れないウィンドウを作成するのは少し抵抗があります。

そこで今回自分はEditorPrefsを利用して情報を保持する方法を採用しました。
EditorPrefsに保存されていればプレイモードの切り替えでも情報が初期化される事はありませんし、シミュレーションの仕組みはエディタ拡張寄りの実装ですから、情報の置き場としても自然に感じます。

EditorPrefsについては「EditorPrefs - Unity スクリプトリファレンス」にあります。

// シミュレーションする回数を保存しておく。
EditorPrefs.SetInt("SimulationCountKey", simulationCount);

// シミュレーションを完了した回数を保存しておく。
EditorPrefs.SetInt("FinishCountKey", finishCount);

// シミュレーション回数が不足していたら次のシミュレーションを開始する。
var simulationCount = EditorPrefs.GetInt("SimulationCountKey");
var finishCount = EditorPrefs.GetInt("FinishCountKey");
if (finishCount < simulationCount)
{
    // 次のシミュレーションの処理。
}

シミュレーション時に保持するべき情報が多い場合、個別に保存していると管理コストが高くついてしまうので、シリアライズ可能なデータクラスを定義し、それをJSON形式にシリアライズして一度に保存してしまうのがおすすめです。

Unityエディタ上でのシミュレーションを終了する

コマンドラインでの実行時に-quitを指定していない場合、シミュレーションを終了するタイミングで明示的にUnityエディタを終了させる必要があります。
Unityエディタの終了にはEditorApplication.Exitを実行します。ドキュメントは「Unity - Scripting API: EditorApplication.Exit」です。

EditorApplication.Exit(0);

なお、シミュレーションの結果についてはこのメソッドで返すことは難しいため、別途テキストで書き出すのが良いと思います。

まとめ

以上、簡単ではありますが、シミュレーションの機能を開発するうえで学んだポイントをまとめました。
ここで紹介した機能を利用することでシミュレーションの外枠については迷わず実行することができるようになると思います。

明日は@michel_mayonakaさんです!

2
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
2
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?