Skip to content

Latest commit

 

History

History
885 lines (553 loc) · 49.6 KB

README_ja.md

File metadata and controls

885 lines (553 loc) · 49.6 KB

Anjin

Meta file check openupm

Click English for English page if you need.

Anjinは、Unity製ゲーム向けのオートパイロット フレームワークです。 次の2つの要素で構成されています。

  1. ゲーム中にロードされたSceneに応じて、対応するAgentを起動するディスパッチャ
  2. Sceneに閉じた自動実行を実現するAgent

Agentとは、UI操作のプレイバックやモンキーテストなど、特定の操作を実行する小さく切り分けられたC#スクリプトです。 ビルトインで提供しているもののほか、ゲームタイトル固有のものを実装して使用できます。

インストール方法

主に2通りの方法でインストールできます。

Package Manager ウィンドウを使用する場合

  1. Project Settings ウィンドウ(Editor > Project Settings)にある、Package Manager タブを開きます
  2. Scoped Registries の下にある + ボタンをクリックし、次の項目を設定します(図 1)
    1. Name: package.openupm.com
    2. URL: https://package.openupm.com
    3. Scope(s): com.dena, com.cysharp, and com.nowsprinting
  3. Package Managerウィンドウを開き(Window > Package Manager)、レジストリ選択ドロップダウンで My Registries を選択します(図 2)
  4. com.dena.anjin パッケージの Install ボタンをクリックします

図 1. Project Settings ウィンドウの Package Manager タブ

図 2. Package Manager ウィンドウのレジストリ選択ドロップダウン

Note

scopesに com.cysharpcom.nowsprinting を忘れず追加してください。Anjin内で使用しています。

Note

Anjinパッケージ内のテストを実行する場合(package.jsonの testables に追加するとき)は、Unity Test Framework パッケージ v1.3以上が必要です。

openupm-cli を使用する場合

openupm-cli がインストールされている状態で、ターミナルから次のコマンドを実行します。

openupm add com.dena.anjin

Assembly Definition FileのDefine Constraintsに UNITY_INCLUDE_TESTS || DENA_AUTOPILOT_ENABLE が設定されていますので、原則リリースビルドからは除外されます。

推奨.gitignore

Anjinを起動すると、次のファイルが自動生成されます。 トラッキングする必要はありませんので、プロジェクトの.gitignoreファイル(もしくはお使いのVCSの無視設定)に追加することを推奨します。

/[Aa]ssets/[Aa]utopilot[Ss]tate.asset*

また、Automated QAパッケージの機能を使用すると、次のファイルが生成されます。 これらも同様に無視設定することを推奨します。

/[Aa]ssets/[Aa]utomated[Qq][Aa]*
/[Aa]ssets/[Rr]ecordings*

ゲームタイトルごとの設定

ゲームタイトルのUnityプロジェクトにUPMパッケージをインストール後、以下の設定・実装を行います。

  • AutopilotSettings.assetファイルを生成、設定
  • 使用するAgentの.assetファイルを生成・設定
  • 必要に応じてカスタムAgentの実装
  • 必要に応じて初期化処理の実装

Note

ゲームタイトル固有のオートパイロット向けコードは、属するAssembly Definition FileのDefine Constraintsに UNITY_INCLUDE_TESTS || DENA_AUTOPILOT_ENABLE を設定することで、リリースビルドから除外できます

オートパイロット設定ファイル(.asset)の生成

UnityエディタのProjectウィンドウで右クリックしてコンテキストメニューを開き、 Create > Anjin > Autopilot Settings を選択すると生成できます。 ファイル名は任意で、プロジェクト内に複数作成して使い分けできます。

大きく3つの設定項目があります。

Agent割り当て設定

Scene Agent MappingとフォールバックAgent

Sceneごとに自動実行を行なうAgent設定ファイル(.asset)の対応付けを設定します。

リストになっていますので、SceneAgent の組み合わせを設定してください。並び順は動作に影響しません。 リストに存在しないSceneでは、Fallback Agentに設定されたAgentが使用されます。

たとえば全てのSceneで UGUIMonkeyAgent が動くようにしたければ、Scene Agent Maps は空に、 Fallback Agent には UGUIMonkeyAgent の.assetファイルを設定します。

Scene横断Agents

Scene Agent Maps および Fallback Agentとは独立して、Sceneを横断して実行されるAgentを設定します。

指定されたAgentの寿命はオートパイロット本体と同じになります(つまり、DontDestroyOnLoad を使用します)。 たとえば、ErrorHandlerAgentUGUIEmergencyExitAgent などを指定します。

Warning

実行中に例外が発生した時点でオートパイロットを中断するために、ErrorHandlerAgent の設定をお勧めします。

オートパイロット実行時間設定

実行時間
実行時間上限を秒で指定します。デフォルトは300秒で、0を指定すると無制限に動作します。 この項目は、コマンドラインから上書きもできます(後述)。
終了コード
オートパイロットの実行時間が満了したときに使用される終了コードを選択します
カスタム終了コード
終了コードを整数値で指定します
メッセージ
オートパイロットの実行時間が満了したとき、Reporterから送信されるメッセージ

オートパイロット実行設定

擬似乱数シード
疑似乱数発生器に与えるシード値を固定したいときに指定します(省略可)。なお、これはオートパイロットの使用する疑似乱数発生器に関する設定であり、ゲーム本体の疑似乱数発生器シードを固定するにはゲームタイトル側での実装が必要です。 この項目は、コマンドラインから上書きもできます(後述)。
タイムスケール
Time.timeScaleを指定します。デフォルトは1.0。 この項目は、コマンドラインから上書きもできます(後述)。
出力ルートパス
Agent、Logger、および Reporter が出力するファイルのルートディレクトリパスを指定します。相対パスが指定されたときの起点は、エディターではプロジェクトルート、プレーヤーでは Application.persistentDataPath になります。 この項目は、コマンドラインから上書きもできます(後述)。
スクリーンショット出力パス
Agent が撮影するスクリーンショットの出力ディレクトリ パスを指定します。相対パスが指定されたとき、outputRootPath が起点となります。 この項目は、コマンドラインから上書きもできます(後述)。
スクリーンショットを消去
オートパイロットを起動するとき、screenshotsPath 下のスクリーンショットを消去します
Loggers
オートパイロットが使用するLogger指定します。省略時は Debug.unityLogger がデフォルトとして使用されます
Reporters
オートパイロット終了時に通知を行なうReporterを指定します

Agent設定ファイル(.asset)の生成

ビルトインのAgentを使用する場合でも、カスタムAgentを実装した場合でも、Unityエディタでそのインスタンス(.assetファイル)を生成する必要があります。

インスタンスは、UnityエディタのProjectウィンドウで右クリックしてコンテキストメニューを開き、 Create > Anjin > Agent名 を選択すると生成できます。ファイル名は任意です。

生成したファイルを選択すると、インスペクタにAgent固有の設定項目が表示され、カスタマイズが可能です。 同じAgentでも設定の違うものを複数用意して、Sceneによって使い分けることができます。

Logger設定ファイル(.asset)の生成

Loggerインスタンスは、UnityエディタのProjectウィンドウで右クリックしてコンテキストメニューを開き、 Create > Anjin > Logger名 を選択すると生成できます。ファイル名は任意です。

生成したファイルを選択すると、インスペクタにLogger固有の設定項目が表示され、カスタマイズが可能です。 同じLoggerでも設定の違うものを複数用意して使い分けることができます。

Reporter設定ファイル(.asset)の生成

Reporterインスタンスは、UnityエディタのProjectウィンドウで右クリックしてコンテキストメニューを開き、 Create > Anjin > Reporter名 を選択すると生成できます。ファイル名は任意です。

生成したファイルを選択すると、インスペクタにReporter固有の設定項目が表示され、カスタマイズが可能です。 同じReporterでも設定の違うものを複数用意して使い分けることができます。

実行方法

次の3通りの方法で、Unityエディタ内でオートパイロットを実行できます。

1. Unityエディタ(GUI)の再生モードで実行

実行したい設定ファイル(AutopilotSettings)をインスペクタで開き、実行 ボタンをクリックすると、オートパイロットが起動します。 設定された実行時間が経過するか、停止 ボタンクリックで停止します。

Tip

編集モードからオートパイロットを起動したとき、オートパイロットが停止すると編集モードに戻ります。 再生モードの状態でオートパイロットを起動すると、オートパイロットを停止しても再生モードは継続されます。

2. コマンドラインから起動

コマンドラインから起動する場合、以下の引数を指定します。

$(UNITY) \
  -projectPath $(PROJECT_HOME) \
  -batchmode \
  -executeMethod DeNA.Anjin.Editor.Commandline.Bootstrap \
  -AUTOPILOT_SETTINGS Assets/Path/To/AutopilotSettings.asset

なお、

  • UNITYにはUnityエディタへのパス、PROJECT_HOMEには自動実行対象プロジェクトのルートを指定します
  • -AUTOPILOT_SETTINGS に続けて、実行したい設定ファイル(AutopilotSettings)のパスを指定します
  • -quit は指定しないでください(Play modeに入らず終了してしまいます)
  • -nographics は指定しないでください(GameViewウィンドウを表示できません)

また、以下の引数を追加することで一部の設定を上書きできます。 各引数の詳細は前述の「オートパイロット設定ファイル」の同名項目を参照してください。

LIFESPAN_SEC
実行時間上限を秒で指定します
RANDOM_SEED
疑似乱数発生器に与えるシード値を固定したいときに指定します
TIME_SCALE
Time.timeScaleを指定します。デフォルトは1.0
OUTPUT_ROOT_DIRECTORY_PATH
Agent、Logger、および Reporter が出力するファイルのルートディレクトリパスを指定します
SCREENSHOTS_DIRECTORY_PATH
Agent が撮影するスクリーンショットの出力ディレクトリパスを指定します
GAME_VIEW_WIDTH
GameView の幅を設定します。この引数は、コマンド ラインからエディターを起動する場合にのみ使用されます。デフォルト値は 640 です
GAME_VIEW_HEIGHT
GameView の高さを設定します。この引数は、コマンド ラインからエディターを起動する場合にのみ使用されます。デフォルト値は 480 です

いずれも、キーの先頭に-を付けて-LIFESPAN_SEC 60のように指定してください。

Important

バッチモードでも GameView ウィンドウが表示されます。 Xvfbでも動作することを確認していますが、Unityの正式なサポートではないため、将来利用できなくなる恐れはあります。

3. Play Modeテスト内で実行

静的メソッド Launcher.LaunchAutopilotAsync(string) を使用することで、テストコード内でオートパイロットが動作します。 引数には AutopilotSettings ファイルパスを指定します。

[Test]
public async Task LaunchAutopilotInTest()
{
  // 最初のSceneをロード("Scenes in Build" に含まれている必要があります)
  await SceneManager.LoadSceneAsync("Title");

  // オートパイロットを起動
  await Launcher.LaunchAutopilotAsync("Assets/Path/To/AutopilotSettings.asset");
}

Warning

テストのデフォルトタイムアウトは3分です。オートパイロットの実行時間が3分を超える場合は Timeout 属性でタイムアウト時間を指定してください。

Warning

テストをプレイヤーで実行するときは、必要な設定ファイルを Resources フォルダに置き、ビルドに含まれるようにしてください。テストのプレイヤービルドに処理を挟むには IPrebuildSetup および IPostBuildCleanup が利用できます。 ファイルパスは Resources フォルダからの相対パスを拡張子(".asset")なしで指定します。

Note

テストランナーに LogException または LogError 出力を検知されると、そのテストは失敗と判定されます。エラーハンドリングをAnjinで行なう前提で LogAssert.ignoreFailingMessages で抑止してもいいでしょう。

Note

複数のシナリオを連続実行する場合、AutopilotSettings.outputRootPath に個別のパスを指定することで出力ファイルを保全できます。

ビルトインAgent

以下のAgentが用意されています。これらをそのまま使用することも、ゲームタイトル固有のカスタムAgentを実装して使用することも可能です。

UGUIMonkeyAgent

uGUIのコンポーネントをランダムに操作するAgentです。 実装にはオープンソースのtest-helper.monkeyパッケージを使用しています。

このAgentのインスタンス(.assetファイル)には以下を設定できます。

実行時間
ランダム操作の実行時間を秒で指定します。0を指定するとほぼ無制限(TimeSpan.MaxValue)に動作します。この設定でAgentが終了してもオートパイロットおよびアプリ自体は終了しません。次にSceneが切り替わるまでなにもしない状態になります
操作間隔
ランダム操作間のウェイト間隔をミリ秒で指定します
要素なしタイムアウト
指定した秒数の間、対話可能なUI/2D/3D要素が出現しなければ、オートパイロットの実行を中断します
クリック&ホールド時間
クリック&ホールドの継続時間をミリ秒で指定します
Gizmos を有効
もし有効ならモンキー操作中の GameView に Gizmo を表示します。もし無効なら GameView に Gizmo を表示しません

スクリーンショット設定:

有効
スクリーンショット撮影を有効にします
ファイル名
デフォルト値を使用: スクリーンショットのファイル名のプレフィックスにデフォルト値を使用します。デフォルト値はAgentの名前です
プレフィックス: スクリーンショットのファイル名のプレフィックスを指定します
拡大係数
解像度をあげるための係数。ステレオキャプチャモードと同時には設定できません
ステレオキャプチャモード
ステレオレンダリングが有効な場合にどちらのカメラを使用するかを指定できます。拡大係数と同時には設定できません

UGUIMonkeyAgent によって操作されたくない GameObject がある場合、 TestHelper.Monkey.Annotations アセンブリに含まれる IgnoreAnnotation コンポーネントをアタッチしておくことで操作を回避できます。 詳しくは後述のAnjin Annotationsを参照してください。

UGUIPlaybackAgent

Automated QAパッケージのRecorded Playback機能でレコーディングしたuGUI操作を再生するAgentです。

このAgentのインスタンス(.assetファイル)には以下を設定できます。

操作を記録したJSONファイル
Automated QAパッケージのRecorded Playbackウィンドウで記録したJSONファイルを設定します

Automated QAによる操作のレコーディングは、Unityエディターのメニューから Automated QA > Automated QA Hub > Recorded Playback で開くウィンドウから行ないます。 レコーディングファイル(.json)は Assets/Recordings/ フォルダ下に保存されますが、移動・リネームは自由です。

なお、Automated QAのRecorded Playback機能ではScene遷移をまたがって操作を記録ができますが、AnjinではSceneが切り替わったところでAgentも強制的に切り替わるため、再生も中断されてしまいます。 従って、レコーディングはScene単位に区切って行なうようご注意ください。

Important

Automated QAパッケージは、再生に失敗(対象のボタンが見つからないなど)したときコンソールに LogType.Error を出力します。これを検知してオートパイロットを停止するには、次の設定が必要です。

  1. ErrorHandlerAgent を追加し、Handle ErrorTerminate Autopilot に設定します
  2. ConsoleLogger を追加し、Filter LogTypeError 以上を設定します

Important

Automated QAパッケージはプレビュー段階のため、破壊的変更や、パッケージ自体の開発中止・廃止もありえる点、ご注意ください。

DoNothingAgent

なにもしないAgentです。

このAgentのインスタンス(.assetファイル)には以下を設定できます。

実行時間
なにもしない時間を秒で指定します。0を指定すると無制限になにもしません。この設定でAgentが終了してもオートパイロットおよびアプリ自体は終了しません。次にSceneが切り替わるまでなにもしない状態になります

TerminateAgent

オートパイロットの実行を停止します。テストシナリオの目標を達成した後などに実行されることを想定しています。

このAgentのインスタンス(.assetファイル)には以下を設定できます。

終了コード
このAgentがオートパイロットを停止するときに使用される終了コードを選択します
カスタム終了コード
終了コードを整数値で入力します
メッセージ
オートパイロットを停止するとき、Reporterから送信されるメッセージ

ParallelCompositeAgent

複数のAgentを登録し、それを並列実行するAgentです。

このAgentのインスタンス(.assetファイル)には以下を設定できます。

Agents
並列実行するAgentのリスト。CompositeAgentを指定して入れ子にすることも可能です

SerialCompositeAgent

複数のAgentを登録し、それを直列実行するAgentです。

このAgentのインスタンス(.assetファイル)には以下を設定できます。

Agents
直列実行するAgentのリスト。CompositeAgentを指定して入れ子にすることも可能です

OneTimeAgent

1つの子Agentを登録し、それをオートパイロット実行期間を通じて1回だけ実行できるAgentです。 2回目以降の実行はスキップされます。

たとえば、タイトル画面で初回だけ導線が異なる、ホーム画面で初回だけログインボーナス受け取りがあるといったゲームにおいて、 通信エラーなどによるタイトル画面戻しが発生してもそのまま実行するテストシナリオを構築できます。

このAgentのインスタンス(.assetファイル)には以下を設定できます。

Agent
1回だけ実行できるAgent。CompositeAgentを指定して入れ子にすることも可能です

RepeatAgent

1つの子Agentを登録し、それを無限に繰り返し実行するAgentです。

SerialCompositeAgentと組み合わせることで、一連の操作を何周もしたり、特定のAgentだけを繰り返し実行することができます。 なお、有限回の繰り返しはサポートしません(SerialCompositeAgentで実現できるため)。

このAgentのインスタンス(.assetファイル)には以下を設定できます。

Agent
繰り返し実行するAgent。CompositeAgentを指定して入れ子にすることも可能です

TimeBombAgent

内包するAgentが終了する前に解除メッセージを受信しないと失敗するAgent。

例えば、アウトゲームのチュートリアル(スマホゲームなどuGUIのタップ操作で完遂できるもの)を突破するには、次のように設定します。

  1. UGUIMonkeyAgentAgent に設定します。進行するボタン以外は操作できないはずです。実行時間 は少し余裕をもって設定してください
  2. チュートリアル完遂時にログに出力されるメッセージを 解除メッセージ に設定します

このAgentのインスタンス(.assetファイル)には以下を設定できます。

Agent
実際に動作するAgent。このAgentが先に終了すると、TimeBombAgentは失敗します。
解除メッセージ
このメッセージが先にログに出力されたら、TimeBombAgentは正常終了します。正規表現でも指定できます。

ErrorHandlerAgent

異常系のログメッセージを捕捉してオートパイロットの実行を停止するAgentです。

常に、他の(実際にゲーム操作を行なう)Agentと同時に起動しておく必要があります。 一般的には、AutopilotSettingsScene Crossing Agents に追加します。 Sceneごとに設定を変えたい場合は、ParallelCompositeAgent と合わせて使用します。

このAgentのインスタンス(.assetファイル)には以下を設定できます。

例外を検知
例外ログを検知したとき、オートパイロットを停止するか、レポート送信のみ行なうかを指定します。 コマンドライン引数 -HANDLE_EXCEPTION で上書きできますが、複数のErrorHandlerAgentを定義しているとき、すべて同じ値で上書きされますので注意してください。
エラーを検知
エラーログを検知したとき、オートパイロットを停止するか、レポート送信のみ行なうかを指定します。 コマンドライン引数 -HANDLE_ERROR で上書きできますが、複数のErrorHandlerAgentを定義しているとき、すべて同じ値で上書きされますので注意してください。
アサートを検知
アサートログを検知したとき、オートパイロットを停止するか、レポート送信のみ行なうかを指定します。 コマンドライン引数 -HANDLE_ASSERT で上書きできますが、複数のErrorHandlerAgentを定義しているとき、すべて同じ値で上書きされますので注意してください。
警告を検知
警告ログを検知したとき、オートパイロットを停止するか、レポート送信のみ行なうかを指定します。 コマンドライン引数 -HANDLE_WARNING で上書きできますが、複数のErrorHandlerAgentを定義しているとき、すべて同じ値で上書きされますので注意してください。
無視するメッセージ
指定された文字列を含むログメッセージは停止条件から無視されます。正規表現も使用できます。エスケープは単一のバックスラッシュ (`\`) です。

Tip

実行中に例外が発生した時点でオートパイロットを中断するために「例外を検知」を停止に設定することを推奨します。

UGUIEmergencyExitAgent

Sceneに含まれる EmergencyExitAnnotations コンポーネントの出現を監視し、表示されたら即クリックするAgentです。 たとえば通信エラーや日またぎで「タイトル画面に戻る」ボタンのような、テストシナリオ遂行上イレギュラーとなる振る舞いが含まれるゲームで利用できます。

常に、他の(実際にゲーム操作を行なう)Agentと同時に起動しておく必要があります。 一般的には、AutopilotSettingsScene Crossing Agents に追加します。 Sceneごとに設定を変えたい場合は、ParallelCompositeAgent と合わせて使用します。

このAgentのインスタンス(.assetファイル)には以下を設定できます。

間隔
EmergencyExitAnnotationコンポーネントの出現を確認する間隔をミリ秒で指定します
スクリーンショット
EmergencyExitボタンクリック時にスクリーンショットを撮影します

ビルトインLogger

以下のLoggerタイプが用意されています。これらをそのまま使用することも、ゲームタイトル固有のカスタムLoggerを実装して使用することも可能です。

ConsoleLogger

ログをコンソールに出力するLoggerです。

このLoggerのインスタンス(.assetファイル)には以下を設定できます。

フィルタリングLogType
選択したLogType以上のログ出力のみを有効にします

FileLogger

ログを指定ファイルに出力するLoggerです。

このLoggerのインスタンス(.assetファイル)には以下を設定できます。

出力ファイルパス
ログファイルの出力先パスを指定します。相対パスが指定されたとき、AutopilotSettings.outputRootPathが起点となります。 コマンドライン引数 -FILE_LOGGER_OUTPUT_PATH で上書きできますが、複数のFileLoggerを定義しているとき、すべて同じ値で上書きされますので注意してください。
フィルタリングLogType
選択したLogType以上のログ出力のみを有効にします
タイムスタンプを追加
ログエンティティにタイムスタンプを出力します

ビルトインReporter

以下のReporterタイプが用意されています。これらをそのまま使用することも、ゲームタイトル固有のカスタムReporterを実装して使用することも可能です。

JUnitXmlReporter

JUnit XMLフォーマットのレポートファイルを出力するReporterです。 オートパイロット実行の成否は、Unityエディターの終了コードでなくこのファイルを見て判断するのが確実です。errors, failuresともに0件であれば正常終了と判断できます。

このReporterのインスタンス(.assetファイル)には以下を設定できます。

出力ファイルパス
JUnit XML形式ファイルの出力先パスを指定します。相対パスが指定されたとき、AutopilotSettings.outputRootPathが起点となります。 コマンドライン引数 -JUNIT_REPORT_PATH で上書きできますが、複数のJUnitXmlReporterを定義しているとき、すべて同じ値で上書きされますので注意してください。

SlackReporter

Slackにレポート送信するReporterです。

このReporterのインスタンス(.assetファイル)には以下を設定できます。

Slackトークン
Slack通知に使用するBotのOAuthトークン。省略時は送信されません。 コマンドライン引数 -SLACK_TOKEN で上書きできますが、複数のSlackReporterを定義しているとき、すべて同じ値で上書きされますので注意してください。
Slackチャンネル
Slack通知を送るチャンネルID(例: \"C123456\")をカンマ区切りで指定します。省略時は送信されません。 チャンネルにはBotを招待しておく必要があります。 コマンドライン引数 -SLACK_CHANNELS で上書きできますが、複数のSlackReporterを定義しているとき、すべて同じ値で上書きされますので注意してください。
メンション宛先ユーザーグループID
エラー終了時に送信する通知をメンションするユーザーグループのIDをカンマ区切りで指定します
@hereをつける
エラー終了時に送信する通知に@hereを付けます
リード文
エラー終了時に送信する通知のリード文。OSの通知に使用されます。"{message}" のようなプレースホルダーを指定できます
メッセージ
エラー終了時に送信するメッセージ本文のテンプレート。"{message}" のようなプレースホルダーを指定できます
エラー終了時に送信するメッセージのアタッチメントに指定する色(デフォルト:Slackの "danger" と同じ赤色)
スクリーンショット
エラー終了時にスクリーンショットを撮影します(デフォルト: on)
正常終了時にも送信
正常終了時にもレポートを送信します(デフォルト: off)

Slack Botは次のページで作成できます。
Slack API: Applications

Slack Botには次の権限が必要です。

  • chat:write
  • files:write

リード及びメッセージ本文のテンプレートに記述できるプレースホルダーは次のとおりです。

  • "{message}": 終了要因メッセージ(エラーログのメッセージなど)
  • "{settings}": 実行中の AutopilotSettings 名
  • "{env.KEY}": 環境変数
  • "{mppm-tags}": Multiplayer Play Mode パッケージのタグ

ゲームタイトル固有の実装

ゲームタイトル固有のカスタムAgentや初期化処理を実装する場合、リリースビルドへの混入を避けるため、専用のアセンブリに分けることをおすすめします。 Assembly Definition File (asmdef) のAuto Referencedをoff、Define Constraintsに UNITY_INCLUDE_TESTS || DENA_AUTOPILOT_ENABLE を設定することで、リリースビルドからは除外できます。

このasmdef及び格納フォルダは、Projectウィンドウの任意の場所でコンテキストメニューを開き Create > Anjin > Game Title Specific Assembly Folder を選択することで生成できます。

ゲームタイトル固有の初期化処理

ゲームタイトル固有の初期化処理が必要な場合、初期化を行なう静的メソッドに InitializeOnLaunchAutopilot 属性を付与してください。 オートパイロットの起動処理の中でメソッドを呼び出します。

[InitializeOnLaunchAutopilot]
public static void InitializeOnLaunchAutopilotMethod()
{
    // ゲームタイトル固有の初期化処理
}

非同期メソッドにも対応しています。

[InitializeOnLaunchAutopilot]
private static async UniTask InitializeOnLaunchAutopilotMethodAsync()
{
    // ゲームタイトル固有の初期化処理
}

Note

引数に呼び出し順序を指定できます。値の低いメソッドから順に呼び出されます。

Note

オートパイロットの起動処理は、RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)RuntimeInitializeOnLoadMethodのデフォルト)で実行しています。 またRuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)で、Configurable Enter Play Modeのための初期化処理を実装しています。

カスタムAgent

カスタムAgentは、Anjin.Agents.AbstractAgent を継承して作ります。 メソッド UniTask Run(CancellationToken) に、Agentが実行する処理を実装するだけです。

AbstractAgent に定義された以下のフィールドを利用できます。各インスタンスは Run メソッド呼び出し前に設定されています。

  • Logger : UnityEngine.ILogger の実装です。AutopilotSettingsで設定されたLoggerがセットされます。Agent内のログ出力にはこちらを使用してください
  • Random : Anjin.Utilities.IRandom の実装です。AutopilotSettingsもしくは起動時引数で指定されたシードから作られています

なお、[CreateAssetMenu]アトリビュートを設定しておくとコンテキストメニューからインスタンス生成ができて便利です。

カスタムLogger

カスタムLoggerは、Anjin.Logers.AbstractLoggerAsset を継承して作ります。 UnityEngine.ILogger の実装を返すプロパティ Logger { get; } を実装する必要があります。

なお、[CreateAssetMenu]アトリビュートを設定しておくとコンテキストメニューからインスタンス生成ができて便利です。

カスタムReporter

カスタムReporterは、Anjin.Reporters.AbstractReporter を継承して作ります。 メソッド UniTask PostReportAsync() を実装するだけです。

なお、[CreateAssetMenu]アトリビュートを設定しておくとコンテキストメニューからインスタンス生成ができて便利です。

Anjin Annotations

Anjinの操作を制御するためのアノテーションを定義しています。 DeNA.Anjin.Annotations アセンブリをAssembly Definition Referencesに追加して使用してください。 仕組み上、リリースビルドに含まれることになりますのでご注意ください。

Note

アノテーションアセンブリをリリースビルドから除いても、アセットバンドルビルドされたSceneやPrefabにはアノテーションコンポーネントへのリンクが残ります。 そのため、インスタンス化の際に警告ログが出力されてしまいます。 これを回避するため、リリースビルドにアノテーションアセンブリを含めるようにしています。

IgnoreAnnotation

このコンポーネントがアタッチされたGameObjectは、UGUIMonkeyAgentによって操作されることを避けることができます。

EmergencyExitAnnotations

このコンポーネントがアタッチされたButtonが表示されると、UGUIEmergencyExitAgentはすぐにクリックを試みます。 通信エラーや日またぎで「タイトル画面に戻る」ボタンのような、テストシナリオ遂行上イレギュラーとなるボタンに付けることを想定しています。

Multiplayer Play Mode パッケージと使用する

Unity 6以降で利用できる Multiplayer Play Mode(以下MPPM)パッケージを使用することで、マルチプレイ対応ゲームの動作確認を簡単に行えるようになりました。

AnjinをMPPMパッケージと使用するときの注意点を以下に示します。 MPPMパッケージ v1.3.1で確認しています。

Virtual Playersで実行する

Virtual Players で実行する場合、編集モードからAutopilotSettingsファイルの 実行 ボタンをクリックすると、すべてのVirtual Playerでオートパイロットが起動します。

再生モードからの起動および、プレイヤーによって異なるAutopilotSettingsを使用することはできません。 プレイヤーごとに異なる振る舞いを指示するには、タグ によって分岐するカスタムAgentを実装する必要があります。

AutopilotSettingsの「出力ルートパス」に相対パスを指定したとき、起点は各Virtual Playerのディレクトリになります。 従って、FileLoggerやスクリーンショットはVirtual Playerごとに保全されます。

Caution

UGUIPlaybackAgent が依存しているAutomated QAパッケージは、出力ファイルを Application.persistentDataPath に書き出します。 すべてのVirtual Playerが同じファイルに書き込もうとするため、コンソールにエラーが出力されます。

Warning

Virtual PlayersにはAssets下のファイルがシンボリックリンクで共有されます。 そのため、インスペクタで設定を変更したときは、再実行する前にメニューの File > Save (command + S) で保存する必要があります。

Play Mode Scenariosで実行する

Play Mode Scenarios で実行する場合、Anjinを組み込んだプレイヤービルドが必要になります。 ビルド方法については プレイヤービルドでの実行 を参照してください。

Play Mode Scenariosではプレイヤーごとにコマンドライン引数を指定して起動することができるため、異なるAutopilotSettingsファイルを使用できます。

Caution

UGUIPlaybackAgent が依存しているAutomated QAパッケージは、出力ファイルを Application.persistentDataPath に書き出します。 すべてのVirtual Playerが同じファイルに書き込もうとするため、コンソールにエラーが出力されます。

プレイヤービルドでの実行[実験的機能]

Anjinをプレイヤービルドに含めることで、プレイヤー(実機)でもオートパイロットを実行できます。

Warning

この機能は実験的機能です。 また、Anjin本体はメモリアロケーションなどをあまり気にせず作られています。パフォーマンステストに使うときは注意してください。

ビルド方法

1. カスタムスクリプトシンボル DENA_AUTOPILOT_ENABLE および COM_NOWSPRINTING_TEST_HELPER_ENABLE を設定する

カスタムスクリプトシンボルを設定します。設定方法はUnityマニュアルの カスタム製スクリプトシンボル - Unity マニュアル を参照してください。

2. 設定ファイルをビルドに含める

必要な設定ファイルを Resources フォルダに置き、ビルドに含まれるようにしてください。 プレイヤービルドに処理を挟むには IPreprocessBuildWithReport および IPostprocessBuildWithReport が利用できます。

3. iCloudバックアップ対象から外す(任意)

プレイヤー実行では、ビルトインのFile LoggerやAgentのスクリーンショットなどは Application.persistentDataPath 下に出力されます。 このパスはデフォルトでiCloudバックアップ対象のため、不要であれば除外します。

UnityEngine.iOS.Device.SetNoBackupFlag(Application.persistentDataPath);

4. デバッグメニューにオートパイロット起動ボタンを追加する(任意)

たとえば UnityDebugSheet から起動するには次のようにします。

AddButton("Launch autopilot", clicked: () =>
  {
    _drawerController.SetStateWithAnimation(DrawerState.Min); // 先にデバッグメニューを閉じる

#if UNITY_EDITOR
    const string Path = "Assets/Path/To/AutopilotSettings.asset";
#else
    const string Path = "Path/To/AutopilotSettings"; // Resourcesからの相対パスを指定。拡張子(.asset)は不要です
#endif
    Launcher.LaunchAutopilotAsync(Path).Forget();
});

Note

Launcher.LaunchAutopilotAsync は、引数に AutopilotSettings インスタンスを渡すオーバーロードも使用できます。

起動方法

デバッグメニューから起動するほか、コマンドライン引数で起動を指示できます。 コマンドラインから実行する場合、以下の引数を指定します。

$(ROM) -LAUNCH_AUTOPILOT_SETTINGS Path/To/AutopilotSettings

なお、

  • ROM にはプレイヤービルド実行ファイルのパスを指定します
  • -LAUNCH_AUTOPILOT_SETTINGS には、実行したい設定ファイル(AutopilotSettings)のパスを指定します。パスは Resources フォルダからの相対パスで、拡張子(.asset)は不要です

ほか、エディターでの実行と同じ引数を指定できます。

Note

プレイヤー実行では、ビルトインのFile LoggerやAgentのスクリーンショットなどは Application.persistentDataPath 下に出力されます。
各プラットフォームのパスはUnityマニュアルの Application.persistentDataPath を参照してください。

Note

Androidはコマンドライン引数の指定方法が異なります。Unityマニュアルの Android プレイヤーのコマンドライン引数を指定する - Unity マニュアル を参照してください。

トラブルシューティング

オートパイロットは停止しているのに AutopilotSettings の Run ボタンが表示されない

Anjinの実行状態を永続化している AutopilotState.asset が不正な状態になっている恐れがあります。 インスペクタで開いて リセット ボタンをクリックしてください。

それでも解決しない場合、 AutopilotState.asset を削除してみてください。

プロジェクトを再生モードにすると勝手にオートパイロットが動いてしまう

Anjinの実行状態を永続化している AutopilotState.asset が不正な状態になっている恐れがあります。 インスペクタで開いて リセット ボタンをクリックしてください。

それでも解決しない場合、 AutopilotState.asset を削除してみてください。

[CompilerError] Argument 1: Cannot convert to 'System.Threading.CancellationToken'

次のコンパイルエラーが発生するケースが報告されています。

[CompilerError] Argument 1:.
Cannot convert from 'DeNA.Anjin.Reporters.SlackReporter.CoroutineRunner' to 'System.Threading.CancellationToken'
Compiler Error at Library\PackageCache\[email protected]\Runtime\Reporters\SlackReporter.cs:66 column 53

これは、プロジェクトにインストールされているUniTaskがv2.3.0未満のときに発生します。 この箇所で使用している UniTask.WaitForEndOfFrame(MonoBehaviour) は、UniTask v2.3.1で追加されたAPIです。

通常、インストール方法に従っていれば適正なバージョンのUniTaskがインストールされます。 しかし、プロジェクトに埋め込みパッケージとしてUniTaskが配置されていたりすればそちらが優先されてしまいます。 Unityエディターが生成するPackages/packages-lock.jsonの中身を確認するか、お使いのIDEのコード定義ジャンプ機能で UniTask.WaitForEndOfFrame() のソースファイルがどこにあるかを確認するなどして、古いUniTaskがインストールされている原因を突き止められます。

起動時に "settings has been obsolete" 警告が出る

たとえば次のような警告メッセージが出力されることがあります。

Slack settings in AutopilotSettings has been obsolete.
Now, automatically converted it to SlackReporter asset file. Check it out and commit it to your VCS.

これは、廃止された設定項目を新しい設定方法(上例では SlackReporter )に自動変換したことを示しています。 設定ファイルが更新されていますので、確認してVCS(Gitなど)にコミットしてください。

スクリーンショットがSlackに投稿されない

Anjin v1.8.3 以降、SlackReporterにはチャンネル名(例: "#channel")ではなくチャンネルID(例: "C123456")を指定してください。

ライセンス

MIT License

コントリビュート

IssueやPull requestを歓迎します。 Pull requestには enhancement, bug, chore, documentation といったラベルを付けてもらえるとありがたいです。 ブランチ名から自動的にラベルを付ける設定もあります。PR Labeler settings を参照してください。

おおまかな機能追加の受け入れ方針は次のとおりです。

  • すべてのビルトイン機能は、Unityエディタのインスペクタウィンドウで設定を完結して使用できること
  • Autopilot本体への機能追加は極力避け、Agentなどによる拡張を検討する
  • 汎用的でないAgentの追加は控える。ブログやGistでの公開、もしくはSamplesに置くことを検討する

次の機能要望およびPull requestは、Anjinのコンセプトに反するためリジェクトされます。

  • 複数のテストシナリオ(AutopilotSettings)を連続実行する機能。Play Modeテストから実行する機能を利用してください
  • AutopilotSettingsに「開始Scene」を指定できる機能。どのSceneからでも動作するテストシナリオを組むことを推奨しています

開発方法

本リポジトリをUnityプロジェクトのサブモジュールとして Packages/ ディレクトリ下に置いてください。

ターミナルから次のコマンドを実行します。

git submodule add https://github.com/dena/Anjin.git Packages/com.dena.anjin

Warning

Anjinパッケージ内のテストを実行するためには、次のパッケージのインストールが必要です。

テスト専用のUnityプロジェクトを生成し、Unityバージョンを指定してテストを実行するには、次のコマンドを実行します。

make create_project
UNITY_VERSION=2019.4.40f1 make -k test

リリースワークフロー

Actions > Create release pull request > Run workflow を実行し、作られたpull requestをデフォルトブランチにマージすることでリリース処理が実行されます。 (もしくは、デフォルトブランチのpackage.json内のバージョン番号を書き換えます)

リリース処理は、Releaseワークフローで自動的に行われます。 tagが付与されると、OpenUPMがtagを収集して更新してくれます。

以下の操作は手動で行わないでください。

  • リリースタグの作成
  • ドラフトリリースの公開