概要
開発者は、アクション、アクションセット、ゲームの入力構成を構築する基本構造を定義する、ゲーム内アクション(in-game action/IGA)ファイルを提供する必要があります。 この記事では、このファイルの全体的な構造を説明し、多様なゲームからいくつかの具体例を紹介します。
ファイルの例
ゲーム内アクションファイルを手動で作成
まずは、上記のリンク付きの例からゲーム内アクション(IGA)ファイルを1つダウンロードします。 次に、Steamフォルダー内にcontroller_configディレクトリ(通常はC:/Program Files (x86)/Steam/controller_config)を作成し、そのディレクトリにファイルを保存します。 Steamフォルダー内にはよく似た名前のフォルダーがありますので、"controller_base"フォルダーではなく、"controller_config"フォルダー内に保存してください。 ファイル名を次のように変更します: "game_actions_X.vdf"。Xの部分にはゲームのSteam AppIDが入ります。 ゲームのSteam AppIDがわからない場合は、Steamパートナーサイトにログインして確認してください。
そのファイルをお好みのテキストエディターで開いてください。 ファイルはKeyValuesと呼ばれるValveの標準形式で、シンプルで読みやすい形式となっています。 参考として、ゲーム内アクションファイルテンプレートや、Portal 2 IGAをダウンロードすると便利です。
Steam入力APIを使用する既存のゲームからIGAファイルを作成する
Steam上の任意のゲームの設定をローカル設定として保存している場合、対応するファイルは次の場所にあります:
[SteamDirectory]\UserData\[あなたのユーザーID]\241100\remote\controller_config\[appid]\[savename].vdf
こちらが一般的なWindows 10マシンに保存された
Defender's Questのローカル設定の例です。
これらのファイルは開発者がアップロードしたマスターIGAファイルの完全なレプリカではありませんが、マスターファイルから直接引用された「アクション」と「ローカリゼーション」ブロックを見ることで、オリジナルの設定のために参考となるアイデアを得られます。
スクリーンショット内のファイルのダウンロードリンクは
#library_controllersavedefaulttitle_0.vdfです。
Defender's QuestのマスターIGAと比較することを推奨します。
IGAフォーマット
IGAファイルはVDFドキュメント形式をとります。これは、キーと値の文字列をペアにして、構造化オブジェクトデータを作成するValveの独自のデータ形式です。
スケルトン
ファイルの基本構造は「ゲーム内アクション」という名前のラッパーオブジェクトと、「アクション」、「ローカリゼーション」とそれぞれ名付けられた2つのサブオブジェクトです。
"In Game Actions"
{
"actions"
{
}
"localization"
{
}
}
アクションセット
「アクション」オブジェクトを見てみましょう。 このオブジェクトにはアクションセットが入ります。 「アクション」オブジェクトの構造はこのようになります:
"actions"
{
"ActionSetNameGoesHere"
{
"title" "#TitleGoesHere"
"StickPadGyro"
{
}
"AnalogTrigger"
{
}
"Button"
{
}
}
}
文字列
"ActionSetNameGoesHere"
と
"#TitleGoesHere"
は、上述の例のための文字列ですので、置き換える必要がありますが、それ以外はそのまま使用するキーワードです。
"ActionSetNameGoesHere"
と置き換える値は、Steam入力APIで使用するアクションセット名です。
"#TitleGoesHere"
に置き換える値は、ファイル後半の
"localization"
セクションで使用するローカリゼーショントークンとなります。 ここでは#記号が必要なことに注意してください。
各アクションセットには一意の文字列名を付ける必要があり、「アクション」コンテナオブジェクトのスコープ内にオブジェクトを作成することで、追加できます。 JSONではなくVDFなので、コンマや角かっこは不要です。
各アクションセットオブジェクトがとることのできるサブオブジェクトは3つあります。
"StickPadGyro"
、
"AnalogTrigger"
、
"Button"
です。 これらのみが定義可能なオブジェクトであり、個別のアクション定義を格納するコンテナーとなります。 3つのカテゴリーをすべて提供する必要はありませんが、
この構造は完全に有効です。例:
"actions"
{
"ActionSetName1"
{
"title" "#Title1"
"AnalogTrigger"
{
}
"Button"
{
}
}
"ActionSetName2"
{
"title" "#Title2"
"StickPadGyro"
{
}
}
"ActionSetName3"
{
"title" "#Title3"
"Button"
{
}
}
}
StickPadGyroこのアクションセットブロックは、最大2つのモーション軸を持つアナログアクション用で、ジョイ
スティックやトラック
パッド、
ジャイロスコープなどへのバインドに適しています。 また、マウスのようなデバイスでコントロールしたいものも該当します。
AnalogTriggerこのアクションセットブロックは、単一のモーション軸を持つアナログアクション用で、アナログトリガーへバインドします。
Buttonこのアクションセットブロックはオン/オフ状態のみを報告する純粋なデジタルアクション用です。 このブロックの名前は「ボタン」ですが、デジタルアクションはあらゆる物理的な入力にバインド可能です。ジョイスティック、トラックパッドなどのようなアナログデータの出力用に元々デザインされているものも対象にできます。
アクション
IGAファイルはアクションの定義があって初めて意味を持ちます。早速追加しましょう!
StickPadGyroアクションまずは
StickPadGyro
(2軸アナログ)アクションを追加してみましょう。 キャラクターを動かすものを「Move」、カメラをコントロールするものを「Camera」と呼ぶこととします。
"actions"
{
"FPSControls"
{
"title" "#Set_FPSControls"
"StickPadGyro"
{
"Move"
{
"title" "#Action_Move"
"input_mode" "joystick_move"
}
"Camera"
{
"title" "#Action_Camera"
"input_mode" "absolute_mouse"
}
}
}
}
StickPadGyro
アクションの抽象的な構造は次の通りです:
"ActionNameHere"
{
"title" "#ActionTitleHere"
"input_mode" "<analog_mode>"
}
この構造内でユーザーが編集可能なのは"ActionNameHere"、"#ActionTitleHere"、"<analog_mode>"のみです。 それぞれがSteam入力API内で使用するアクションの文字列名、このファイルのローカリゼーションセクションで使用するローカリゼーションキー、アナログデータの処理と解釈の方法を管理する入力ソースモードに対応しています。
"input_mode"
プロパティは、
StickPadGyro
アクション用に2つの値をとることが可能です:
"joystick_move"
"absolute_mouse"
値がジョイスティックとして解釈されるアクション(中心点からの一定のたわみ)には
"joystick_move"
を、
より柔軟な汎用アナログアクションには
"absolute_mouse"
を使用します。 どちらにすべきか分からない場合は、
"absolute_mouse"
を使用して下さい。
"joystick_move" 対 "absolute_mouse"
ファーストパーソンゲーム、サードパーソンゲーム用やカーソル駆動型ゲームにカメラ入力を作成する時は必ず、"absolute_mouse"タイプを使用し、マウスと同じようにデルタに反応させます。
APIはスティックベースの入力に対して自動的に正しく動作するので、カメラが(PS4/Xboxスタイルの)アナログスティックに適用されているのであれば、完全なデッドゾーン/応答曲線等と共にターン可能なスティック入力を得ることができます。 デッドゾーン等はデフォルト設定で指定できます。 この同じ入力は、ジョイスティック、トラックパッド、モーションコントロールジャイロ(Steamコントローラ/PS4)、に使うことができ、将来的にはマウスもサポートします。
"joystick_move" ベースの入力方法をカメラに使用するべきではありません。パッド/ジャイロ/マウス/モーションコントロールでは有効な 1:1 データを反対方向にマッピングできないからです。
これはカーソルベースの入力でも同じです - スティックベース入力では"absolute_mouse" はカーソルとして問題なく使えるので、ゲーム用に専用のスティックベースのカーソルを作る必要はありません。オプションで、アナログデータと共に低レベルのマウスイベントを送信できます。 ゲームは、マウスイベントとオペレーティングシステムから作成されたイベントを区別することはできません。 区別させるには、値
"os_mouse"
を追加して、1を割り当てます。
以下がその例です。
"StickPadGyro"
{
"Mouse"
{
"title" "#Action_Mouse"
"input_mode" "absolute_mouse"
"os_mouse" "1"
}
}
AnalogTrigger アクションAnalogTriggerアクションは、トリガーにバインドできる1Dのアナログアクションです。 銃の発射や「照準」モードの開始に、トリガーの単純なしきい値を使用している場合、AnalogTriggerアクションの代わりに Buttonアクションを使用すると、ユーザーはより柔軟に再バインドすることができます。
AnalogTriggerアクションには、再バインドUIで設定できるデッドゾーンがあり、これらの値の間で0〜1.0fに再スケーリングされます。 Nintendo Switch Proコントローラーのようなデジタルトリガーボタンを備えたコントローラは、0または1.0のいずれかを送信するため、ゲームプレイのコードが、時間の経過とともに徐々に変化するトリガーに依存していないことを確認することをお勧めします。
AnalogTriggerアクションのフォーマットは単純で、キーがアクション名で、値がローカリゼーショントークンになります。 以下がその例です:
"AnalogTrigger"
{
"AccelerationAxis" "#Action_Accelerate"
"BreakingAxis" "#Action_Brake"
}
ButtonアクションButtonアクションも同様のフォーマットで、アクション名とローカリゼーショントークンを使用します。
"Button"
{
"digital_action_1_name_here" "#DigitalAction1TitleHere"
"digital_action_2_name_here" "#DigitalAction2TitleHere"
}
必要に応じて、アクションと同時に発生するネイティブの低レベル入力ハードウェアイベント(ネイティブのマウスクリックなど)を定義できます。 これは、ゲームが7層もの複雑な入力スタックに依存しているような極端な場合に役立ちます。例えば、アプリケーション層でシミュレートされたマウスイベントを、オペレーティングシステムが直接生成したものと「
完全に」同じように処理できないような場合です。
"Button"
{
"simple_click" "#simple_click"
"fancy_click" "#fancy_click, mouse_button LEFT"
}
これにより、 ゲームは"fancy_click"アクションが呼び出されるたびに、実際のオペレーティングシステムレベルの左マウスボタンイベントを送信します。
警告!
このトリックは、アクションを特定の固定入力バインドに強制させるための支えとして使用しないでください。 なぜなら、これは "入力ではなくアクション" という概念やユーザーに完全な設定コントロールを提供するという目的に完全に反しているからです。 特殊な状況に対応する場合にとどまらずにこの機能を使用している場合、使いすぎです。アクションセットレイヤー
アクションセットに加え、アクションセットレイヤーで、アクティブなアクションセットへの増分変更をオーバーレイすることもできます。 これを使用すると、OnFootコントロール上にSniperレイヤーを配置するような一般モードの特殊処理や、通常のゲームプレイに投票画面などのポップアップを表示するゲーム内UIがある場合の処理を行うことができます。 レイヤーは、個別のセクションで宣言します。例:
"action_layers"
{
"IngameModalLayer"
{
"title" "#Layer_IngameModal"
"legacy_set" "0"
"set_layer" "1"
"parent_set_name" "InGame"
"AnalogTrigger"
{
}
"Button"
{
"Modal_Accept" "#Action_Modal_Accept"
"Modal_Decline" "#Action_Modal_Decline"
}
}
}
ローカリゼーション
マスターIGAファイルには、アクションセット定義と一緒にローカリゼーションセクションを含める必要があります。 ローカリゼーションオブジェクトの個々の子オブジェクトは、Steamがサポートするいずれかの言語の文字列になります。 少なくとも、英語のアクションタイトルを含むブロックを1つ含めてください。
"localization"
{
"english"
{
"move" "Move"
"camera" "Camera"
}
}
プロパティ名は、「#」記号がないことを除いて、前のセクションで指定したローカリゼーションキーに対応している必要があることに注意してください。
言語を追加する場合は、各エントリーにローカライズされたテキストを含む言語ブロックを追加するだけです。
"localization"
{
"english"
{
"move" "Move"
"camera" "Camera"
}
"japanese"
{
"move" "移動"
"camera" "カメラ"
}
"norwegian"
{
"move" "Bevege"
"camera" "Kamera"
}
}
各言語のトークンは「API言語コード」と一致する必要があります(例:簡体字中国語の場合「schinese」)。 Steamがサポートする言語のリストは
こちらを参照してください。
SteamによるあなたのIGAファイルの取り扱い
作成したマスターIGAファイルは、開発期間中にのみ使用されます(ただし、バージョン管理システムなどに保存し、管理する必要があります)。
開発中にゲームの公式入力設定を作成すると、Steamクライアントは、ひな型となるテンプレートとしてマスターIGAファイルを使用します。