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()