(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]

Xbox360&OneやPS3&4など様々なコントローラーへの対応が簡単に出来るInControl【Unity】【アセット】


このエントリーをはてなブックマークに追加

この記事でのバージョン
Unity 2018.3.4f1
InControl 17.3


はじめに

UnityはInputクラスを使う事で、コントローラーへの対応が比較的簡単に行えます。



しかし、様々なコントローラーに対応しようとすると途端に面倒になります。

例えばデフォルトの状態だと、Xboxコントローラーのスタートボタンと

PS4のR2 ボタンが同じ入力として扱われる、みたいな感じです。


そこで今回紹介するのが、様々なコントローラーへの対応が簡単に出来るInControlというアセットです。



ありとあらゆるコントローラーやプラットフォームに対応しており、


f:id:kan_kikuchi:20190420105009j:plain


特にPC向けのゲームを作る際に実装時間を大幅に削減出来るオススメアセットです。


なお、本記事ではコントローラーへの対応しか紹介していませんが、

キーボードやマウス、タッチ操作にも対応出来るようです。(未確認)


導入

まずは導入からです。


アセットストアからダウンロード&インストールした後、

上部メニューのInControl ->Setup Input Managerを実行します。


f:id:kan_kikuchi:20190420105332j:plain
f:id:kan_kikuchi:20190420105827j:plain


すると、ProjectSettings/InputManager.assetファイルが再生成されます。

なお、このファイルはEdit -> Project SettingsのInputから確認する事が出来ます。

(自動で設定されているので、以降は変更しないようにしましょう)


f:id:kan_kikuchi:20190420110252j:plain
f:id:kan_kikuchi:20190420110308j:plain


ちなみにこれを行わないとエラーが表示されて使えません。


f:id:kan_kikuchi:20190420105843j:plain



次に上部メニューのGameObject -> InControl -> Managerを実行します。


f:id:kan_kikuchi:20190420105554j:plain


するとシーン上にInCeontrolというオブジェクトが生成されます。

(各種設定はとりあえず変更しなくてOK)


f:id:kan_kikuchi:20190420105603j:plain


これで導入は完了です。


プログラム

ここからは実装に入力を処理するプログラムの話です。

なお、InControlのクラスを使う際にはusing InControlが必要になります。



まず、接続されているコントローラーはInputManagerのActiveDevice(s)で取得できます。

//接続されているコントローラー1つを取得
InputDevice activeDevice = InputManager.ActiveDevice;

//接続されているコントローラー全てを取得
ReadOnlyCollection<InputDevice> activeDevices = InputManager.ActiveDevices;


ちなみに何も接続されていない場合でもActiveDeviceはnullにならないので、

接続されていない事を判定するにはInputDevice.Nullを使う必要があります。

//接続されているコントローラー1つを取得
InputDevice activeDevice = InputManager.ActiveDevice;

//コントローラーが接続されているかチェック
if (activeDevice == InputDevice.Null) {
  //コントローラーが何も接続されていない時の処理
}


次にコントローラーの入力はInputControlで取得出来ます。

//接続されているコントローラー1つを取得
InputDevice activeDevice = InputManager.ActiveDevice;

//右トリガーの入力情報を取得
InputControl rightTriggerControl = activeDevice.GetControl(InputControlType.RightTrigger);
        
//右トリガーが押されたかチェック
if (rightTriggerControl.IsPressed) {
  Debug.Log("RightTriggerが押された!");
}


なお、InputControlを取得せずともInputDeviceから直接入力を取得する事も可能です。

//接続されているコントローラー1つを取得
InputDevice activeDevice  = InputManager.ActiveDevice;

//右トリガーが押されたかチェック
if (activeDevice.RightTrigger.IsPressed) {
  Debug.Log("RightTriggerが押された!");
}


ただし全ての入力をInputDeviceから直接取得出来るわけではありません。

例えばPS4のShareボタンみたいにちょっと特殊なボタンはInputControlを使う必要があります。


なお、取得出来る情報は押されたかどうか(IsPressed)だけではなく、

離された(WasReleased)、押されていた(WasPressed)などの色々な情報が取得出来ます。


f:id:kan_kikuchi:20190530115740j:plain


同様に、スティックの傾きを取得する事も簡単に出来ます。

//接続されているコントローラー1つを取得
InputDevice activeDevice = InputManager.ActiveDevice;

//左スティックの入力情報を取得
TwoAxisInputControl leftStickControl = activeDevice.LeftStick;

//左スティックの入力ベクトルを取得
Vector2 leftStickVector = leftStickControl.Vector;


スティックの入力についても、XやYだけの入力といった様々な情報が取得出来ます。


f:id:kan_kikuchi:20190530115900j:plain


また、コントローラーの接続状況が変化された時のイベントも用意されています。

//新しいコントローラーが接続された
InputManager.OnDeviceAttached += inputDevice => Debug.Log( "Attached: " + inputDevice.Name );

//接続されていたコントローラーが外れた
InputManager.OnDeviceDetached += inputDevice => Debug.Log( "Detached: " + inputDevice.Name );

//使われているコントローラーが変わった
InputManager.OnActiveDeviceChanged += inputDevice => Debug.Log( "Switched: " + inputDevice.Name );