以下のゲームパッド検出のチュートリアルをやっているのですが
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;
}
パッドがおかしいのかと思って、試しに「ElecHead」を起動すると、きちんと使えるんですよねえ……これが。
ElecHeadはたしかパッドのインデックスは0番目しか指定していませんでした。
ですのでxinputの1番スロットしか動かない状態のはずなんで動いているのが不思議ですね。
まじですか!?何回も確認したんですが普通に使えてますよ!
今回ハマってるエレコムのJC-U3613Mというパッドは背面にXinputを使うかDirectInputを使うか切り替える物理スイッチがあって、XinputでもDirectInputでもElecHeadは普通にゲーム出来てます。(さすがにゲーム中に物理スイッチを切り替えると動かなくなりますが、起動時にどっちかにしておくと、どっちも普通に動きます)あ!これもしかするとSteamクライアントが何かしてるかもです(違ったらすいません💦)
steamクライアントがなんかしてるのは確かにありそうですね...
試しに古いバージョンのGameMakerにコピペしてやってみます。どうかなあ……
v2.2.3.433
v2.3.1.542
v2.3.3.574
でやってみましたが動作は同じですねえ。DirectInputでは十字キーは使えないです。
GameMaker側のバージョン依存とかではなく、別の所ですかねえ。でも「ElecHead」がXinputだけというので少し安心出来たので、Xinputだけ考えておけば大丈夫かなあとも思い始めました
バージョンとっかえひっかえしてたら最大ログイン数の制限(?初めて見たので不明)を超えてしまって入れない。(古いバージョンだから出るもので今はそういうの無い可能性もありますが)
↑↑↑ この最大ログイン数の問題はYoYoのアカウントページからセッションの削除が可能で解決しました。
・DirectInputコントローラーのマッピングは各メーカーによって異なっている。
(実際にはある程度の類型があるとは思われる)
・マッピングがgamepad_get_mapping()で得られない場合はヒントが無くマッピングのセットができない。
(どのボタンが内部でなんと呼ばれているか不明)得られたとして各メーカーで違う可能性がある
b0とかb1とかかもしれないけどその実装もメーカーによって違う可能性
記号を総当たりで探し当てるのはやめたほうがいい
ぐるぐるですじゃー
んもうXinputでいきます。
DirectInputのパッド使ってる人はXinputに置き換え出来るドライバ入れて置き換えたりしてる人もいるみたいですし、Steamクライアントも確かにそういうことしてるみたいです。なので時代はXinput。でいいかなって。
置き換え出来るってことは出来るのかも、とも少し思うけど
いったんここまでにしておきます。ありがとうございました。
十字キーが何か反応してたり入れ替わってたり、例えばgp_face1で上とかになってたり、右押すとshoulderrbが反応するとかだったらGameMaker側で置き換え出来るんですが、無反応なので…
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
うおおおおお!!ありがとうございます!!
参考にさせて頂きます!!!感謝感激です!!!
さらに調べてみたら、DirectInputでもキーマッピングを自分で作れば、GameMakerが持っているXInput対応の関数でキー動作を取得できました。
サンプルと同じ様に処理したいときは、マッピングを自分で作るといいかもしれません。
とりあえずJC-U3613Mだけ動けばいいなら以下のようにすると動きました。
キーマップ指示用文字列を作って、「gamepad_test_mapping」でそれを適用するという流れです。
プログラムを動かすとmappingに入っているキーマップ文字列は以下のようになりました。
キーマッピングは以下のヘルプで説明されていました。
https://manual.yoyogames.com/GameMaker_Language/GML_Reference/Game_Input/GamePad_Input/gamepad_test_mapping.htm
どうしてもDirectInputのコントローラーで対応したいなら、キー設定画面などを作って、ユーザーの設定をmappinng文字列に直してgamepad_test_mappingに渡してあげるようにすれば、どのようなコントローラーでも対応できそうです。
ありがとうございます!色々出来そうですね!