GameMaker 日本語掲示板

DirectInputコントローラーの動作

14 コメント
views
17 フォロー

以下のゲームパッド検出のチュートリアルをやっているのですが
https://gamemaker.io/en/blog/coffee-break-tutorials-setting-up-and-using-gamepads-gml

手持ちのDirectInputコントローラーがうまく動作せず原因がよくわからないので
トピックを作らせて頂きました。

スティックと十字キーの入力を得ようとしているのですが
スティックしか動作せず、十字キーの入力がとれない状況です。

Xinputの場合は問題なく両方動作します。
念のため同時接続するパッドは他に無い、1つだけ挿すようにしています。

Windows11pro 21H2
IDE v2022.2.0.625
Runtime v2022.3.0.497 です

ゲームパッドのスロットは0~3がXinput 4~11がDirectInputということで、4以降になってるのは確認できています。

obj_playerのStepイベントの所だけ以下のように改変しています
なにか単純なバグなら良いのですが。

追記:
gamepad_button_count() は13を返します。エレコムのJC-U3613Mというパッドを使ってるんですが
この13個というボタン数はゲームパッドのボタン割り当てユーティリティに出て来るボタン数と同じです。
しかし十字キーはPOVとしてユーティリティに表示されててボタン数とは別カウントみたいなんですよねえ……

//スティック
var h_move = gamepad_axis_value(pad_num, gp_axislh);
var v_move = gamepad_axis_value(pad_num, gp_axislv);

//十字キー
var hD_move = gamepad_button_check(pad_num, gp_padr) - gamepad_button_check(pad_num, gp_padl);
var vD_move = gamepad_button_check(pad_num, gp_padd) - gamepad_button_check(pad_num, gp_padu);

//スティック
if((h_move != 0)||(v_move != 0)){
	x += h_move * 4;
	y += v_move * 4;
}

//十字キー
if((hD_move != 0)||(vD_move != 0)){
	x += hD_move * 4;
	y += vD_move * 4;
}

画像1
画像1

ぽんでり
作成: 2022/04/22 (金) 01:17:10
最終更新: 2022/04/24 (日) 01:36:38
通報 ...
1
ぽんでり 2022/04/22 (金) 14:21:56

パッドがおかしいのかと思って、試しに「ElecHead」を起動すると、きちんと使えるんですよねえ……これが。

3
生高橋 2022/04/22 (金) 20:15:12 >> 1

ElecHeadはたしかパッドのインデックスは0番目しか指定していませんでした。
ですのでxinputの1番スロットしか動かない状態のはずなんで動いているのが不思議ですね。

4
ぽんでり 2022/04/22 (金) 21:14:28 修正 >> 3

まじですか!?何回も確認したんですが普通に使えてますよ!
今回ハマってるエレコムのJC-U3613Mというパッドは背面にXinputを使うかDirectInputを使うか切り替える物理スイッチがあって、XinputでもDirectInputでもElecHeadは普通にゲーム出来てます。(さすがにゲーム中に物理スイッチを切り替えると動かなくなりますが、起動時にどっちかにしておくと、どっちも普通に動きます)あ!これもしかするとSteamクライアントが何かしてるかもです(違ったらすいません💦
画像1

8
生高橋 2022/04/23 (土) 02:00:50 >> 3

steamクライアントがなんかしてるのは確かにありそうですね...

2
ぽんでり 2022/04/22 (金) 15:16:46 修正

試しに古いバージョンのGameMakerにコピペしてやってみます。どうかなあ……

5
ぽんでり 2022/04/22 (金) 22:41:08 修正 >> 2

v2.2.3.433
v2.3.1.542
v2.3.3.574
でやってみましたが動作は同じですねえ。DirectInputでは十字キーは使えないです。
GameMaker側のバージョン依存とかではなく、別の所ですかねえ。でも「ElecHead」がXinputだけというので少し安心出来たので、Xinputだけ考えておけば大丈夫かなあとも思い始めました

6
ぽんでり 2022/04/22 (金) 23:16:58 >> 5

バージョンとっかえひっかえしてたら最大ログイン数の制限(?初めて見たので不明)を超えてしまって入れない。(古いバージョンだから出るもので今はそういうの無い可能性もありますが)画像1

7
ぽんでり 2022/04/23 (土) 00:28:21 >> 5

↑↑↑ この最大ログイン数の問題はYoYoのアカウントページからセッションの削除が可能で解決しました。

9
ぽんでり 2022/04/23 (土) 13:17:48 修正

・DirectInputコントローラーのマッピングは各メーカーによって異なっている。
   (実際にはある程度の類型があるとは思われる)
・マッピングがgamepad_get_mapping()で得られない場合はヒントが無くマッピングのセットができない。
    (どのボタンが内部でなんと呼ばれているか不明)得られたとして各メーカーで違う可能性がある
    b0とかb1とかかもしれないけどその実装もメーカーによって違う可能性
    記号を総当たりで探し当てるのはやめたほうがいい

ぐるぐるですじゃー
んもうXinputでいきます。

DirectInputのパッド使ってる人はXinputに置き換え出来るドライバ入れて置き換えたりしてる人もいるみたいですし、Steamクライアントも確かにそういうことしてるみたいです。なので時代はXinput。でいいかなって。

置き換え出来るってことは出来るのかも、とも少し思うけど

いったんここまでにしておきます。ありがとうございました。

10
ぽんでり 2022/04/23 (土) 13:54:50

十字キーが何か反応してたり入れ替わってたり、例えばgp_face1で上とかになってたり、右押すとshoulderrbが反応するとかだったらGameMaker側で置き換え出来るんですが、無反応なので…

11

DirectInputのコントローラーでキー入力を取得する方法について気になったので、調べてみました。

私も、ぽんでりさんと同じJC-U3613Mを持っているので、DirectInputモードにして動作をチェックしました。

結論から言うと、JC-U3613Mの十字キーは、hatスイッチ=POVキーと呼ばれるもので、ボタンとは別に動作を取得できることがわかりました。
このコントローラーの十字キーは、

gamepad_hat_count(pad_id)
でハットスイッチの個数を取得して、

gamepad_hat_value(pad_id, hat_switch_num)

で、取得したいハットスイッチの番号(hat_switch_num)を指定することで、押されたボタンがわかります。
※hat_switch_numは0から始まるので、先に取得したハットスイッチ個数-1

Up = 1、Right = 2、Down = 4、Left = 8の値が返ってきます。同時押しされたときは右上なら1と2を足した3が返ってきます。

コントローラーのボタンは、

・軸(ぐりぐりのスティック)
・ボタン(AとかYとかLとかRとか普通のボタン)
・ハットスイッチ(十字キーの形が多い?POVキーとも呼ばれる)

の三種類があり、GMSでも取得するために別の関数があります。
今回、ボタンは13個ですが、軸は2つ、ハットスイッチは1つとなります。

このへんに詳しいことが書いてありましたので、参考になりました。
https://manual.yoyogames.com/GameMaker_Language/GML_Reference/Game_Input/GamePad_Input/Gamepad_Input.htm

12
ぽんでり 2022/04/26 (火) 21:17:22 >> 11

うおおおおお!!ありがとうございます!!
参考にさせて頂きます!!!感謝感激です!!!

13
名前なし 2022/04/26 (火) 22:03:53 修正

さらに調べてみたら、DirectInputでもキーマッピングを自分で作れば、GameMakerが持っているXInput対応の関数でキー動作を取得できました。
サンプルと同じ様に処理したいときは、マッピングを自分で作るといいかもしれません。
とりあえずJC-U3613Mだけ動けばいいなら以下のようにすると動きました。

var mapping = gamepad_get_guid(pad_id) + "," + gamepad_get_description(pad_id);
mapping += ",platform:windows,";
mapping += "a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,";
gamepad_test_mapping(pad_id, mapping);

キーマップ指示用文字列を作って、「gamepad_test_mapping」でそれを適用するという流れです。

プログラムを動かすとmappingに入っているキーマップ文字列は以下のようになりました。

6e050320000000000000504944564944,JC-U3613M - DirectInput Mode,platform:Windows,a:b2,b:b3,x:b0,y:b1,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,guide:b10,start:b11,leftstick:b8,rightstick:b9,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,back:b10,

キーマッピングは以下のヘルプで説明されていました。
https://manual.yoyogames.com/GameMaker_Language/GML_Reference/Game_Input/GamePad_Input/gamepad_test_mapping.htm

どうしてもDirectInputのコントローラーで対応したいなら、キー設定画面などを作って、ユーザーの設定をmappinng文字列に直してgamepad_test_mappingに渡してあげるようにすれば、どのようなコントローラーでも対応できそうです。

14
ぽんでり 2022/04/27 (水) 00:17:35 >> 13

ありがとうございます!色々出来そうですね!