ゲームパッド入力

この章ではゲームパッドの入力を検知する方法について解説します。

実行結果

SharpDXを関連付け

必要なパッケージをインストール

  1. 「NuGet」を使った同じやり方で「SharpDX.DirectInput」をインストールします。

DirectInputの設定

ファイルの読み込み処理

  1. 入力処理に必要なファイルを関連付けます。
    using SharpDX.DirectInput;
    
  2. パッド取得用変数を宣言します。
    // ゲームパッド取得用変数
    private Joystick _joy;
    
  3. パッド取得用の初期化を行います。
    // 入力周りの初期化
    DirectInput dinput = new DirectInput();
    
    // 使用するゲームパッドのID
    var joystickGuid = Guid.Empty;
    // ゲームパッドからゲームパッドを取得する
    if (joystickGuid == Guid.Empty)
    {
        foreach (DeviceInstance device in dinput.GetDevices(DeviceType.Gamepad, DeviceEnumerationFlags.AllDevices))
        {
            joystickGuid = device.InstanceGuid;
            break;
        }
    }
    // ジョイスティックからゲームパッドを取得する
    if (joystickGuid == Guid.Empty)
    {
        foreach (DeviceInstance device in dinput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AllDevices))
        {
            joystickGuid = device.InstanceGuid;
            break;
        }
    }
    
  4. パッド取得用の初期化を行います。
    また、アナログスティックの値の範囲を使いやすいように「0~65535」から「-1000~1000」に変更しています。
    // 見つかった場合
    if (joystickGuid != Guid.Empty)
    {
        // パッド入力周りの初期化
        _joy = new Joystick(dinput, joystickGuid);
        if (_joy != null)
        {
            // バッファサイズを指定
            _joy.Properties.BufferSize = 128;
    
            // 相対軸・絶対軸の最小値と最大値を
            // 指定した値の範囲に設定する
            foreach (DeviceObjectInstance deviceObject in _joy.GetObjects())
            {
                switch (deviceObject.ObjectId.Flags)
                {
                    case DeviceObjectTypeFlags.Axis:
                        // 絶対軸or相対軸
                    case DeviceObjectTypeFlags.AbsoluteAxis:
                        // 絶対軸
                    case DeviceObjectTypeFlags.RelativeAxis:
                        // 相対軸
                        var ir = _joy.GetObjectPropertiesById(deviceObject.ObjectId);
                        if (ir != null)
                        {
                            try
                            {
                                ir.Range = new InputRange(-1000, 1000);
                            }
                            catch (Exception) { }
                        }
                        break;
                }
            }
        }
    }
    

パッド入力処理

  1. パッド入力用の処理を関数として作ります。
    また、挙動確認用のサンプルに入力が合った場合はタイトルバーの文字が変わるようにしておきます。
    // パッド入力処理
    public void UpdateForPad()
    {
        // フォームにフォーカスが無い場合、処理終了
        if (!Focused) { return; }
        // 初期化が出来ていない場合、処理終了
        if (_joy == null) { return; }
    
        // キャプチャするデバイスを取得
        _joy.Acquire();
        _joy.Poll();
    
        // ゲームパッドのデータ取得
        var jState = _joy.GetCurrentState();
        // 取得できない場合、処理終了
        if (jState == null) { return; }
        
        // 以下の処理は挙動確認用
    
        // 挙動確認用:押されたキーをタイトルバーに表示する
        // アナログスティックの左右軸
        bool inputX = true;
        if (jState.X > 300)
        {
            Text = "入力キー:→";
        }
        else if(jState.X < -300)
        {
            Text = "入力キー:←";
        }
        else
        {
            inputX = false;
        }
        // アナログスティックの上下軸
        bool inputY = true;
        if (jState.Y > 300)
        {
            Text = "入力キー:↓";
        }
        else if (jState.Y < -300)
        {
            Text = "入力キー:↑";
        }
        else
        {
            inputY = false;
        }
        // 未入力だった場合
        if(!inputX && !inputY)
        {
            Text = "入力キー:";
        }
    
        // ボタン判定
        if(jState.Buttons[0])
        {
            // 1番ボタンが押されたらフォームが閉じるように処理
            Close();
        }
    }
    
  2. public void UpdateForPad()をメインループ処理から呼び出します。

余談

利便性を上げる工夫

どのようなタイミングでも入力機器からの入力を受け付けるようにしておくことが大切です。
具体的には、

  1. ゲームアプリ起動後に差しても、入力を受け付けず、アプリ起動前に差している必要がある
  2. 複数のパッドが差さっている場合、入力を受け付けないものがある
といった挙動になっていないか、予め手元でテストしておくと安心です。
※大事なので「キーボード入力」でも同じ話題に触れています。

私個人は、もともと 「Xbox One ワイヤレス コントローラー」を使っていたのですが、 2台目は安く済ませて連射検証も行いたかったため 「OPOLAR ゲームコントローラー」を後から買いました。
この2台で上記コードの動作確認をしています。

(安価に購入したり・余った機器を有効活用するなど)ご自身の環境に合わせて是非お試しください。

 

コード

Program.cs

GameForm.cs