single.php

C# Windows.Gaming.Inputでゲームコントローラーのデバイス名を取得する方法

C#のWinFormsプロジェクトで、Windows.Gaming.Input アセンブリを利用してゲームコントローラーのボタンやトリガーのイベントを取得する際にデバイスの名前も一緒に取得する方法を備忘録的に投稿します。

‘Windows.Gaming.Input’ で取得

C#で、Windowsに接続しているゲームコントローラーの状態を取得するには[Windows.Gaming.Input]アセンブリが簡単です。

using Windows.Gaming.Input

利用すると、XboxコントローラーやDualSenseなどWindowsに接続されたゲームコントローラからのボタンやトリガーのイベントが比較的簡単に取得が可能です。

詳しい内容と対処法は、別記事をご覧ください。

イベント発生時のデバイス名を取得

[Windows.Gaming.Input]アセンブリでは、RawInputやHID APIと同様に、ループでWindowsから飛んでくるメッセージを捕捉してゲームコントローラーの状態が取得できます。

また、RawInputやHID APIでは、イベントの発生元(つまりコントローラーデバイス)の名前を取得する手段が用意されています。

しかし[Windows.Gaming.Input]アセンブリでは、ボタンやトリガーへの対応に特化したライブラリなので、デバイスについて構造体やメソッドに用意がありません。

元々用意されていないので、正攻法では取得は無理なんですが[Gamepad]クラスをコントローラーと組み合わせることで、概ね取得が可能でした。

別クラスで[Gamepad]クラスを使った[GamepadInfo]クラスを作ります。

class GamepadInfo
{
    public Gamepad? Gamepad;
    public RawGameController? Raw;
}

このクラスを使って、ゲームコントローラーからのイベントと組み合わせて

Dictionary<Gamepad, GamepadReading> prevStates = new();
List<GamepadInfo> BindGamepads()
{
    var result = new List<GamepadInfo>();

    var gamepads = Gamepad.Gamepads;
    var raws = RawGameController.RawGameControllers;

    int count = Math.Min(gamepads.Count, raws.Count);

    for (int i = 0; i < count; i++)
    {
        result.Add(new GamepadInfo
        {
            Gamepad = gamepads[i],
            Raw = raws[i]
        });
    }

    return result;
}

ループでメッセージを受信する際に、バインドしたクラスからデバイス名を取得します。

private async Task InputLoop()
{
    while (running)
    {
        var list = BindGamepads();

        foreach (var item in list)
        {
            var gamepad = item.Gamepad;
            if(gamepad == null)
            {
                continue;
            }

            var state = gamepad.GetCurrentReading();

            // 初回登録
            if (!prevStates.ContainsKey(gamepad))
            {
                prevStates[gamepad] = state;
                continue;
            }

            var prev = prevStates[gamepad];

            HandleInput(item, prev, state);

            prevStates[gamepad] = state;
        }

        await Task.Delay(16);
    }
}

private void HandleInput(GamepadInfo item, GamepadReading prev, GamepadReading state)
{
    if(item.Raw == null)
    {
        return;
    }

    Debug.WriteLine($"デバイス名:{item.Raw.DisplayName}");
}

まとめ

今回は短い記事ですが、Windows.Gaming.Input アセンブリを利用してゲームコントローラーのボタンやトリガーのイベントを取得する際にデバイス名を取得する方法をについて書きました。

“Windows.Gaming.Input” アセンブリには、接続されたゲームコントローラーのデバイス名を取得するメソッドなどは用意されていませんが、他のクラスを組み合わせることで取得が可能でした。

“Windows.Gaming.Input” アセンブリでゲームコントローラーのデバイス名を取得したい人の参考になれば幸いです。

スポンサーリンク

最後までご覧いただき、ありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です