Microsoft Flight Simulator(2020)でSimConnectを使うためのメモ C#編
ほんの少しですがわかっている情報について記載します。
必要なもの : MSFS2020本体、Visual Studio Community以上で.NET開発を有効
SimConnectのダウンロードとインストール
まずMSFS2020のゲームを起動して、 Help -> Downloads -> SDK Installerを選びインストーラーをダウンロードします。 ダウンロードしたらインストーラーを起動します。
SDKの中にサンプルコードがあり、SimvarWatcherというプロジェクトを開くとMSFSから変数を取得したりEVENTをset/getする事ができるプログラムを閲覧できます。この内容で理解できるのであれば、この記事を読む必要はありません。
SimConnectを使うプログラミングの概要
詳しくはわからないのですが、SimConnectはFSX(Microsoft Flight Simulator X : 古いやつ)時代からあるようで、Prepar3Dというのにもあるようです。そのためWeb上にあるSimConnectを使う方法はMSFS2020以外の情報もごちゃ混ぜになっているので自分が参考にする資料に気を付けてください。
データの取得と設定
まず、データの取得と設定には大きく二種類あります。
どちらもコールバックが必要になるので、イベントハンドラを用います。注意点としてコールバック関数が直接呼ばれるわけではなく、ウィンドウプロシージャによって何かが起きたことを知らせてくれるので、メッセージを受け取ったらデータを受信する処理を行わないとイベントハンドラが呼ばれません。後述します。
EVENT IDsとVariablesについて
EVENT IDs
フラップを動かす or 動かした、ランディングギアを動かす or 動かした、オートパイロットをON/OFFの情報
Variables
飛行機の高度やフラップの位置、ランディングギアのポジション等、オートパイロットのON/OFFの情報
EVENT IDsとVariablesの使い分け
二つとも似たようなことができ詳しく調べられていませんが、それぞれ特性が違うので必要に応じて使い分ける必要があります。
EVENT IDs
EVENTは何かが起こったこと・起こすことを取得したり設定することができます。コックピット視点でオートパイロットのスイッチを押すたびに、AP_MASTERイベントが発生します。そのイベントデータの中にONであれば1、OFFであれば0というデータが入っています。また、AP_MASTERイベントに1を設定すると、オートパイロットがONになります。
注意点として、EVENTでAP_MASTERに1を設定すると、何故かAP_MASTERイベントが発生せず値を取得でき来ません。コックピット視点でボタンを押すか、コントローラーなどのショートカットで設定をするときのみ値を取得できるので、プログラムから操作するときに設定した結果はVariablesで読み取る必要があるようです。
Variables
Variablesは変数ということで、今の状態(飛行機の状態、カメラの状態等)を取得でき、一部は変数に値を設定できます。オートパイロットの状態を変数として取得するにはAUTOPILOT MASTERという変数を読み込む必要があります。BoolでSettableが×という変数なので読みとり専用です。Boolといいながら、C#でプログラムを書く場合には0か1という数値型になっているようです。前述のEVENTでAP_MASTERを1にした場合、設定ができたかどうかは変数のAUTOPILOT MASTERで取得してみないとわからないということになります。
プログラミングのメモ
初期設定
- プロジェクト作成時のテンプレートは、
Windows フォーム アプリケーション (.NET Framework)を選びましょう。似たようなWindows フォーム アプリがありますが違います。 - フォームいらないよ!コンソールでいいよ!っていう場合は、恐らくフォームを非表示にする方法をとるのが楽です。前述のウィンドウプロシージャの処理が必要なので、コンソールアプリでは苦労します。
- x64でビルドするように設定する。
- VSのプロジェクト参照に
Microsoft.FlightSimulator.SimConnectを追加する。SDKをインストールしたフォルダのSimConnect SDK\lib\managed以下にあるはず。
大枠の流れ
- Form1.csとかで
WndProc()をオーバーライド WM_USER_SIMCONNECT(0x0402)を受信したらSimConnect.ReceiveMessage()を呼ぶようにする。- ウィンドウハンドルを取得。
- SimConnectのインスタンス化。
- コールバックの追加(イベントハンドラ)。
- EVENT IDsの登録。
MapClientEventToSimEvent()AddClientEventToNotificationGroup()- ↑このセットを必要なEVENT分繰り返す。
SetNotificationGroupPriority()- Variablesの登録。
AddToDataDefinition()- ↑このセットを必要なVariables分繰り返す。
RegisterDataDefineStruct<>()- EVENTの取得は
SimConnect.OnRecvEvent() - Variablesの取得は2種類
RequestDataOnSimObjectType()→ 単発- 取得したら
SimConnect.OnRecvSimobjectDataByType()が呼ばれる。
- 取得したら
RequestDataOnSimObject()→ 指定した周期- 取得したら
SimConnect.OnRecvSimobjectData()が呼ばれる。
- 取得したら
- EVENTの設定は
TransmitClientEvent() - Variablesの設定は
SetDataOnSimObject()