Click English for English page if you need.
Anjinは、Unity製ゲーム向けのオートパイロット フレームワークです。 次の2つの要素で構成されています。
- ゲーム中にロードされたSceneに応じて、対応するAgentを起動するディスパッチャ
- Sceneに閉じた自動実行を実現するAgent
Agentとは、UI操作のプレイバックやモンキーテストなど、特定の操作を実行する小さく切り分けられたC#スクリプトです。 ビルトインで提供しているもののほか、ゲームタイトル固有のものを実装して使用できます。
主に2通りの方法でインストールできます。
- Project Settings ウィンドウ(Editor > Project Settings)にある、Package Manager タブを開きます
- Scoped Registries の下にある + ボタンをクリックし、次の項目を設定します(図 1)
- Name:
package.openupm.com
- URL:
https://package.openupm.com
- Scope(s):
com.dena
,com.cysharp
, andcom.nowsprinting
- Name:
- Package Managerウィンドウを開き(Window > Package Manager)、レジストリ選択ドロップダウンで My Registries を選択します(図 2)
com.dena.anjin
パッケージの Install ボタンをクリックします
図 1. Project Settings ウィンドウの Package Manager タブ
図 2. Package Manager ウィンドウのレジストリ選択ドロップダウン
Note
scopesに com.cysharp
と com.nowsprinting
を忘れず追加してください。Anjin内で使用しています。
Note
Anjinパッケージ内のテストを実行する場合(package.jsonの testables
に追加するとき)は、Unity Test Framework パッケージ v1.3以上が必要です。
openupm-cli がインストールされている状態で、ターミナルから次のコマンドを実行します。
openupm add com.dena.anjin
Assembly Definition FileのDefine Constraintsに UNITY_INCLUDE_TESTS || DENA_AUTOPILOT_ENABLE
が設定されていますので、原則リリースビルドからは除外されます。
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
を設定することで、リリースビルドから除外できます
UnityエディタのProjectウィンドウで右クリックしてコンテキストメニューを開き、 Create > Anjin > Autopilot Settings を選択すると生成できます。 ファイル名は任意で、プロジェクト内に複数作成して使い分けできます。
大きく3つの設定項目があります。
Sceneごとに自動実行を行なうAgent設定ファイル(.asset)の対応付けを設定します。
リストになっていますので、Scene
と Agent
の組み合わせを設定してください。並び順は動作に影響しません。
リストに存在しないSceneでは、Fallback Agent
に設定されたAgentが使用されます。
たとえば全てのSceneで UGUIMonkeyAgent
が動くようにしたければ、Scene Agent Maps
は空に、
Fallback Agent
には UGUIMonkeyAgent
の.assetファイルを設定します。
Scene Agent Maps
および Fallback Agent
とは独立して、Sceneを横断して実行されるAgentを設定します。
指定されたAgentの寿命はオートパイロット本体と同じになります(つまり、DontDestroyOnLoad
を使用します)。
たとえば、ErrorHandlerAgent
や UGUIEmergencyExitAgent
などを指定します。
Warning
実行中に例外が発生した時点でオートパイロットを中断するために、ErrorHandlerAgent の設定をお勧めします。
- 実行時間
- 実行時間上限を秒で指定します。デフォルトは300秒で、0を指定すると無制限に動作します。 この項目は、コマンドラインから上書きもできます(後述)。
- 終了コード
- オートパイロットの実行時間が満了したときに使用される終了コードを選択します
- カスタム終了コード
- 終了コードを整数値で指定します
- メッセージ
- オートパイロットの実行時間が満了したとき、Reporterから送信されるメッセージ
- 擬似乱数シード
- 疑似乱数発生器に与えるシード値を固定したいときに指定します(省略可)。なお、これはオートパイロットの使用する疑似乱数発生器に関する設定であり、ゲーム本体の疑似乱数発生器シードを固定するにはゲームタイトル側での実装が必要です。 この項目は、コマンドラインから上書きもできます(後述)。
- タイムスケール
- Time.timeScaleを指定します。デフォルトは1.0。 この項目は、コマンドラインから上書きもできます(後述)。
- 出力ルートパス
- Agent、Logger、および Reporter が出力するファイルのルートディレクトリパスを指定します。相対パスが指定されたときの起点は、エディターではプロジェクトルート、プレーヤーでは Application.persistentDataPath になります。 この項目は、コマンドラインから上書きもできます(後述)。
- スクリーンショット出力パス
- Agent が撮影するスクリーンショットの出力ディレクトリ パスを指定します。相対パスが指定されたとき、outputRootPath が起点となります。 この項目は、コマンドラインから上書きもできます(後述)。
- スクリーンショットを消去
- オートパイロットを起動するとき、screenshotsPath 下のスクリーンショットを消去します
- Loggers
- オートパイロットが使用するLogger指定します。省略時は
Debug.unityLogger
がデフォルトとして使用されます - Reporters
- オートパイロット終了時に通知を行なうReporterを指定します
ビルトインのAgentを使用する場合でも、カスタムAgentを実装した場合でも、Unityエディタでそのインスタンス(.assetファイル)を生成する必要があります。
インスタンスは、UnityエディタのProjectウィンドウで右クリックしてコンテキストメニューを開き、 Create > Anjin > Agent名 を選択すると生成できます。ファイル名は任意です。
生成したファイルを選択すると、インスペクタにAgent固有の設定項目が表示され、カスタマイズが可能です。 同じAgentでも設定の違うものを複数用意して、Sceneによって使い分けることができます。
Loggerインスタンスは、UnityエディタのProjectウィンドウで右クリックしてコンテキストメニューを開き、 Create > Anjin > Logger名 を選択すると生成できます。ファイル名は任意です。
生成したファイルを選択すると、インスペクタにLogger固有の設定項目が表示され、カスタマイズが可能です。 同じLoggerでも設定の違うものを複数用意して使い分けることができます。
Reporterインスタンスは、UnityエディタのProjectウィンドウで右クリックしてコンテキストメニューを開き、 Create > Anjin > Reporter名 を選択すると生成できます。ファイル名は任意です。
生成したファイルを選択すると、インスペクタにReporter固有の設定項目が表示され、カスタマイズが可能です。 同じReporterでも設定の違うものを複数用意して使い分けることができます。
次の3通りの方法で、Unityエディタ内でオートパイロットを実行できます。
実行したい設定ファイル(AutopilotSettings)をインスペクタで開き、実行 ボタンをクリックすると、オートパイロットが起動します。 設定された実行時間が経過するか、停止 ボタンクリックで停止します。
Tip
編集モードからオートパイロットを起動したとき、オートパイロットが停止すると編集モードに戻ります。 再生モードの状態でオートパイロットを起動すると、オートパイロットを停止しても再生モードは継続されます。
コマンドラインから起動する場合、以下の引数を指定します。
$(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の正式なサポートではないため、将来利用できなくなる恐れはあります。
静的メソッド 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を実装して使用することも可能です。
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を参照してください。
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
を出力します。これを検知してオートパイロットを停止するには、次の設定が必要です。
- ErrorHandlerAgent を追加し、
Handle Error
をTerminate Autopilot
に設定します - ConsoleLogger を追加し、
Filter LogType
にError
以上を設定します
Important
Automated QAパッケージはプレビュー段階のため、破壊的変更や、パッケージ自体の開発中止・廃止もありえる点、ご注意ください。
なにもしないAgentです。
このAgentのインスタンス(.assetファイル)には以下を設定できます。
- 実行時間
- なにもしない時間を秒で指定します。0を指定すると無制限になにもしません。この設定でAgentが終了してもオートパイロットおよびアプリ自体は終了しません。次にSceneが切り替わるまでなにもしない状態になります
オートパイロットの実行を停止します。テストシナリオの目標を達成した後などに実行されることを想定しています。
このAgentのインスタンス(.assetファイル)には以下を設定できます。
- 終了コード
- このAgentがオートパイロットを停止するときに使用される終了コードを選択します
- カスタム終了コード
- 終了コードを整数値で入力します
- メッセージ
- オートパイロットを停止するとき、Reporterから送信されるメッセージ
複数のAgentを登録し、それを並列実行するAgentです。
このAgentのインスタンス(.assetファイル)には以下を設定できます。
- Agents
- 並列実行するAgentのリスト。CompositeAgentを指定して入れ子にすることも可能です
複数のAgentを登録し、それを直列実行するAgentです。
このAgentのインスタンス(.assetファイル)には以下を設定できます。
- Agents
- 直列実行するAgentのリスト。CompositeAgentを指定して入れ子にすることも可能です
1つの子Agentを登録し、それをオートパイロット実行期間を通じて1回だけ実行できるAgentです。 2回目以降の実行はスキップされます。
たとえば、タイトル画面で初回だけ導線が異なる、ホーム画面で初回だけログインボーナス受け取りがあるといったゲームにおいて、 通信エラーなどによるタイトル画面戻しが発生してもそのまま実行するテストシナリオを構築できます。
このAgentのインスタンス(.assetファイル)には以下を設定できます。
- Agent
- 1回だけ実行できるAgent。CompositeAgentを指定して入れ子にすることも可能です
1つの子Agentを登録し、それを無限に繰り返し実行するAgentです。
SerialCompositeAgentと組み合わせることで、一連の操作を何周もしたり、特定のAgentだけを繰り返し実行することができます。 なお、有限回の繰り返しはサポートしません(SerialCompositeAgentで実現できるため)。
このAgentのインスタンス(.assetファイル)には以下を設定できます。
- Agent
- 繰り返し実行するAgent。CompositeAgentを指定して入れ子にすることも可能です
内包するAgentが終了する前に解除メッセージを受信しないと失敗するAgent。
例えば、アウトゲームのチュートリアル(スマホゲームなどuGUIのタップ操作で完遂できるもの)を突破するには、次のように設定します。
UGUIMonkeyAgent
をAgent
に設定します。進行するボタン以外は操作できないはずです。実行時間
は少し余裕をもって設定してください- チュートリアル完遂時にログに出力されるメッセージを
解除メッセージ
に設定します
このAgentのインスタンス(.assetファイル)には以下を設定できます。
- Agent
- 実際に動作するAgent。このAgentが先に終了すると、TimeBombAgentは失敗します。
- 解除メッセージ
- このメッセージが先にログに出力されたら、TimeBombAgentは正常終了します。正規表現でも指定できます。
異常系のログメッセージを捕捉してオートパイロットの実行を停止するAgentです。
常に、他の(実際にゲーム操作を行なう)Agentと同時に起動しておく必要があります。
一般的には、AutopilotSettings
の Scene Crossing Agents
に追加します。
Sceneごとに設定を変えたい場合は、ParallelCompositeAgent
と合わせて使用します。
このAgentのインスタンス(.assetファイル)には以下を設定できます。
- 例外を検知
- 例外ログを検知したとき、オートパイロットを停止するか、レポート送信のみ行なうかを指定します。
コマンドライン引数
-HANDLE_EXCEPTION
で上書きできますが、複数のErrorHandlerAgentを定義しているとき、すべて同じ値で上書きされますので注意してください。 - エラーを検知
- エラーログを検知したとき、オートパイロットを停止するか、レポート送信のみ行なうかを指定します。
コマンドライン引数
-HANDLE_ERROR
で上書きできますが、複数のErrorHandlerAgentを定義しているとき、すべて同じ値で上書きされますので注意してください。 - アサートを検知
- アサートログを検知したとき、オートパイロットを停止するか、レポート送信のみ行なうかを指定します。
コマンドライン引数
-HANDLE_ASSERT
で上書きできますが、複数のErrorHandlerAgentを定義しているとき、すべて同じ値で上書きされますので注意してください。 - 警告を検知
- 警告ログを検知したとき、オートパイロットを停止するか、レポート送信のみ行なうかを指定します。
コマンドライン引数
-HANDLE_WARNING
で上書きできますが、複数のErrorHandlerAgentを定義しているとき、すべて同じ値で上書きされますので注意してください。 - 無視するメッセージ
- 指定された文字列を含むログメッセージは停止条件から無視されます。正規表現も使用できます。エスケープは単一のバックスラッシュ (`\`) です。
Tip
実行中に例外が発生した時点でオートパイロットを中断するために「例外を検知」を停止に設定することを推奨します。
Sceneに含まれる EmergencyExitAnnotations
コンポーネントの出現を監視し、表示されたら即クリックするAgentです。
たとえば通信エラーや日またぎで「タイトル画面に戻る」ボタンのような、テストシナリオ遂行上イレギュラーとなる振る舞いが含まれるゲームで利用できます。
常に、他の(実際にゲーム操作を行なう)Agentと同時に起動しておく必要があります。
一般的には、AutopilotSettings
の Scene Crossing Agents
に追加します。
Sceneごとに設定を変えたい場合は、ParallelCompositeAgent
と合わせて使用します。
このAgentのインスタンス(.assetファイル)には以下を設定できます。
- 間隔
- EmergencyExitAnnotationコンポーネントの出現を確認する間隔をミリ秒で指定します
- スクリーンショット
- EmergencyExitボタンクリック時にスクリーンショットを撮影します
以下のLoggerタイプが用意されています。これらをそのまま使用することも、ゲームタイトル固有のカスタムLoggerを実装して使用することも可能です。
ログをコンソールに出力するLoggerです。
このLoggerのインスタンス(.assetファイル)には以下を設定できます。
- フィルタリングLogType
- 選択したLogType以上のログ出力のみを有効にします
ログを指定ファイルに出力するLoggerです。
このLoggerのインスタンス(.assetファイル)には以下を設定できます。
- 出力ファイルパス
- ログファイルの出力先パスを指定します。相対パスが指定されたとき、
AutopilotSettings.outputRootPath
が起点となります。 コマンドライン引数-FILE_LOGGER_OUTPUT_PATH
で上書きできますが、複数のFileLoggerを定義しているとき、すべて同じ値で上書きされますので注意してください。 - フィルタリングLogType
- 選択したLogType以上のログ出力のみを有効にします
- タイムスタンプを追加
- ログエンティティにタイムスタンプを出力します
以下のReporterタイプが用意されています。これらをそのまま使用することも、ゲームタイトル固有のカスタムReporterを実装して使用することも可能です。
JUnit XMLフォーマットのレポートファイルを出力するReporterです。 オートパイロット実行の成否は、Unityエディターの終了コードでなくこのファイルを見て判断するのが確実です。errors, failuresともに0件であれば正常終了と判断できます。
このReporterのインスタンス(.assetファイル)には以下を設定できます。
- 出力ファイルパス
- JUnit XML形式ファイルの出力先パスを指定します。相対パスが指定されたとき、
AutopilotSettings.outputRootPath
が起点となります。 コマンドライン引数-JUNIT_REPORT_PATH
で上書きできますが、複数のJUnitXmlReporterを定義しているとき、すべて同じ値で上書きされますので注意してください。
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は、Anjin.Agents.AbstractAgent
を継承して作ります。
メソッド UniTask Run(CancellationToken)
に、Agentが実行する処理を実装するだけです。
AbstractAgent
に定義された以下のフィールドを利用できます。各インスタンスは Run
メソッド呼び出し前に設定されています。
Logger
:UnityEngine.ILogger
の実装です。AutopilotSettingsで設定されたLoggerがセットされます。Agent内のログ出力にはこちらを使用してくださいRandom
:Anjin.Utilities.IRandom
の実装です。AutopilotSettingsもしくは起動時引数で指定されたシードから作られています
なお、[CreateAssetMenu]
アトリビュートを設定しておくとコンテキストメニューからインスタンス生成ができて便利です。
カスタムLoggerは、Anjin.Logers.AbstractLoggerAsset
を継承して作ります。
UnityEngine.ILogger
の実装を返すプロパティ Logger { get; }
を実装する必要があります。
なお、[CreateAssetMenu]
アトリビュートを設定しておくとコンテキストメニューからインスタンス生成ができて便利です。
カスタムReporterは、Anjin.Reporters.AbstractReporter
を継承して作ります。
メソッド UniTask PostReportAsync()
を実装するだけです。
なお、[CreateAssetMenu]
アトリビュートを設定しておくとコンテキストメニューからインスタンス生成ができて便利です。
Anjinの操作を制御するためのアノテーションを定義しています。
DeNA.Anjin.Annotations
アセンブリをAssembly Definition Referencesに追加して使用してください。
仕組み上、リリースビルドに含まれることになりますのでご注意ください。
Note
アノテーションアセンブリをリリースビルドから除いても、アセットバンドルビルドされたSceneやPrefabにはアノテーションコンポーネントへのリンクが残ります。 そのため、インスタンス化の際に警告ログが出力されてしまいます。 これを回避するため、リリースビルドにアノテーションアセンブリを含めるようにしています。
このコンポーネントがアタッチされたGameObject
は、UGUIMonkeyAgent
によって操作されることを避けることができます。
このコンポーネントがアタッチされたButton
が表示されると、UGUIEmergencyExitAgent
はすぐにクリックを試みます。
通信エラーや日またぎで「タイトル画面に戻る」ボタンのような、テストシナリオ遂行上イレギュラーとなるボタンに付けることを想定しています。
Unity 6以降で利用できる Multiplayer Play Mode(以下MPPM)パッケージを使用することで、マルチプレイ対応ゲームの動作確認を簡単に行えるようになりました。
AnjinをMPPMパッケージと使用するときの注意点を以下に示します。 MPPMパッケージ v1.3.1で確認しています。
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 で実行する場合、Anjinを組み込んだプレイヤービルドが必要になります。 ビルド方法については プレイヤービルドでの実行 を参照してください。
Play Mode Scenariosではプレイヤーごとにコマンドライン引数を指定して起動することができるため、異なるAutopilotSettingsファイルを使用できます。
Caution
UGUIPlaybackAgent
が依存しているAutomated QAパッケージは、出力ファイルを Application.persistentDataPath
に書き出します。
すべてのVirtual Playerが同じファイルに書き込もうとするため、コンソールにエラーが出力されます。
Anjinをプレイヤービルドに含めることで、プレイヤー(実機)でもオートパイロットを実行できます。
Warning
この機能は実験的機能です。 また、Anjin本体はメモリアロケーションなどをあまり気にせず作られています。パフォーマンステストに使うときは注意してください。
カスタムスクリプトシンボルを設定します。設定方法はUnityマニュアルの カスタム製スクリプトシンボル - Unity マニュアル を参照してください。
必要な設定ファイルを Resources
フォルダに置き、ビルドに含まれるようにしてください。
プレイヤービルドに処理を挟むには IPreprocessBuildWithReport
および IPostprocessBuildWithReport
が利用できます。
プレイヤー実行では、ビルトインのFile LoggerやAgentのスクリーンショットなどは Application.persistentDataPath
下に出力されます。
このパスはデフォルトでiCloudバックアップ対象のため、不要であれば除外します。
UnityEngine.iOS.Device.SetNoBackupFlag(Application.persistentDataPath);
たとえば 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 マニュアル を参照してください。
Anjinの実行状態を永続化している AutopilotState.asset
が不正な状態になっている恐れがあります。
インスペクタで開いて リセット ボタンをクリックしてください。
それでも解決しない場合、 AutopilotState.asset
を削除してみてください。
Anjinの実行状態を永続化している AutopilotState.asset
が不正な状態になっている恐れがあります。
インスペクタで開いて リセット ボタンをクリックしてください。
それでも解決しない場合、 AutopilotState.asset
を削除してみてください。
次のコンパイルエラーが発生するケースが報告されています。
[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がインストールされている原因を突き止められます。
たとえば次のような警告メッセージが出力されることがあります。
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など)にコミットしてください。
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 Test Framework package v1.4.1 or later
- Test Helper package v1.1.1 or later
テスト専用の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を収集して更新してくれます。
以下の操作は手動で行わないでください。
- リリースタグの作成
- ドラフトリリースの公開