2024/03/28追記:本記事のリメイク記事を書きました。
実装アプローチや、対応デバイスの追加、デバイス変更時イベントの実装など、いろいろ追加/改善しているので、こちらもご確認ください。
【Unity/InputSystem】新・操作中のコントローラーの種類を識別する - 猫茶の研究日誌
https://nekocha.hatenablog.com/entry/2024/03/28/212705
UnityでPCゲームを製作時、使用中のゲームパッドに応じたボタンガイドを作る際に困ったので、メモしておく。
InputSystemで、ゲームパッドの種別による違いを吸収してくれるのはありがたいが、
「いまどのコントローラを使っているか?」 を確かめたいときがあるだろう。
PSコントローラなら「×で決定」、Xboxコントローラなら「Aで決定」、マウス&キーボードなら「左クリックで決定」と、自動で表示を切り替える処理を実装したいときとか...
DualShockGamepad.current.IsPressed()のように書いて済めばよかったのだが、これは不可能だったので、
かわりに筆者がやってみた方法を紹介する。
サンプルソース
早速サンプルソース。この手のものは結論ファーストが良いと最近思ってるので。
動作確認環境:Windows 10, Unity 2021.3.0f1
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.DualShock;
using UnityEngine.InputSystem.XInput;
bool wasPressedLastFrame_DS = false;
bool wasPressedLastFrame_Xbox = false;
bool wasPressedLastFrame_PC = false;
// 以下を毎フレーム回す
// どのHIDが、直前フレームでキーが押されたかを確認する
void CheckIsPressedLastFrame()
{
wasPressedLastFrame_DS = false;
wasPressedLastFrame_Xbox = false;
wasPressedLastFrame_PC = false;
// DualShock(Dual Senceも含む模様)
if (DualShockGamepad.current != null)
{
foreach (var key in DualShockGamepad.current.children)
{
if (key.IsPressed())
{
wasPressedLastFrame_DS = true;
break;
}
}
}
// Xbox
if (XInputController.current != null)
{
foreach (var key in XInputController.current.children)
{
if (key.IsPressed())
{
wasPressedLastFrame_Xbox = true;
break;
}
}
}
// PC(マウス&キーボード)
if (Keyboard.current != null)
{
foreach (var key in Keyboard.current.children)
{
if (key.IsPressed())
{
wasPressedLastFrame_PC = true;
break;
}
}
}
}
解説
「いま使われているか?」は、直前のフレームでいずれかのボタンが押されたかで判別する。
このために、「毎フレーム、それぞれのデバイスについて、すべてのボタンの状態を確認する」 という処理が必要である。
それぞれのデバイス種別ごと、直近に有効であるデバイスを取得する。
Xboxコントローラなら、XInputController.current
で取得できる。
PSコントローラならDualShockGamepad.current
といった具合である。
すべてのボタンの状態を確認する。
InputSystemでは、ゲームパッドそのものからボタンなど、様々なものが「InputControl」抽象クラスを継承している。
このInputControlは親子構造をなしていて、ゲームパッドの子(child)には、その各種ボタンが割り当てられている。
つまり、PSコントローラならDualShockGamepad.current.child
でボタン類の情報を取ってこれる。
幸いなことに、主要なボタン類は一通りゲームパッドの子(child)であるようなので、今回はこれを使う。
あとは、すべてのキーに対してIsPressed()
でキーの状態を取ってくるだけでよい。