InputSystem 2
振動自体は以下のようなコードで簡単に指定できます。
// 左モーターを50%の速さで回転
// 右モーターを停止させる
Gamepad.current?.SetMotorSpeeds(0.5f, 0.0f);
ゲームパッドの左右モーターをそれぞれ1秒ずつ振動させるサンプルスクリプトです。
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
public class GamepadRumbleExample : MonoBehaviour
{
private IEnumerator Start()
{
var gamepad = Gamepad.current;
if (gamepad == null)
{
Debug.Log("ゲームパッド未接続");
yield break;
}
Debug.Log("左モーター振動");
gamepad.SetMotorSpeeds(1.0f, 0.0f);
yield return new WaitForSeconds(1.0f);
Debug.Log("右モーター振動");
gamepad.SetMotorSpeeds(0.0f, 1.0f);
yield return new WaitForSeconds(1.0f);
Debug.Log("モーター停止");
gamepad.SetMotorSpeeds(0.0f, 0.0f);
}
}
上記スクリプトをGamepadRumbleExample.csという名前でUnityプロジェクトに保存し、適当なゲームオブジェクトにアタッチすると、スクリプトが機能するようになります。
ゲームパッドを振動させるためには、予めゲームパッドを接続した状態にしてください。
接続された状態でゲームを実行すると、左右のモーターがそれぞれ1秒間だけ振動して停止します。
以下のコードでゲームパッドの左右モーターを振動させています。
gamepad.SetMotorSpeeds(1.0f, 0.0f);
第1引数に左モーター(低周波)の回転数
第2引数に右モーター(高周波)の回転数
これを0~1の範囲で指定します。
0を指定するとモーターの回転が停止、1を指定すると最大出力でモーターが回転します。
SetMotorSpeeds()メソッドでコントローラのモーターを動かすと、止まらずにずっと振動し続けます。ゲームを停止しても動き続けますので、必ず回転数0を指定して振動を止める処理を入れてください。
以下メソッドを実行すると、Input Systemで管理しているコントローラの振動を一括で停止・再開できます。
// 振動を一時停止
InputSystem.PauseHaptics();
// 振動を再開
InputSystem.ResumeHaptics();
// 振動を停止し、パラメータリセット
InputSystem.ResetHaptics();
InputSystem.PauseHaptics()メソッド
コントローラの振動を一時停止するメソッドです。回転数などの設定値は保持されます。
InputSystem.ResumeHaptics()メソッド
コントローラの振動を再開するメソッドです。保持された設定値で振動が再開されます。
InputSystem.ResetHaptics()メソッド
コントローラの振動を停止し、設定値を初期値にリセットします。
上記メソッドの挙動を確かめるためのサンプルスクリプトです。
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
public class PauseResumeExample : MonoBehaviour
{
private IEnumerator Start()
{
var gamepad = Gamepad.current;
if (gamepad == null)
{
Debug.Log("ゲームパッド未接続");
yield break;
}
var wait = new WaitForSeconds(1.0f);
Debug.Log("左モーター振動");
gamepad.SetMotorSpeeds(1.0f, 0.0f);
yield return wait;
Debug.Log("振動を一時停止");
InputSystem.PauseHaptics();
yield return wait;
Debug.Log("振動を再開");
InputSystem.ResumeHaptics();
yield return wait;
Debug.Log("振動を停止し、パラメータリセット");
InputSystem.ResetHaptics();
yield return wait;
Debug.Log("振動を再開(初期値なので振動しない)");
InputSystem.ResumeHaptics();
yield return wait;
Debug.Log("振動を停止");
InputSystem.ResetHaptics();
}
}
ゲームパッドが接続された状態で起動すると、ゲームパッドの左モーターが2回だけ振動します。
InputSystem.PauseHaptics()
→InputSystem.ResumeHaptics()
の順に呼び出したタイミングでは振動が再開され、
InputSystem.ResetHaptics()
→InputSystem.ResumeHaptics()
の順に呼び出した際は振動しません。
これは、InputSystem.ResetHaptics()
呼び出しの時点で回転数が初期値(=0)に戻っているためです。
Gamepadクラスにアクセスするのではなく、 Player Inputから振動可能なコントローラを取得し、振動させるサンプルです。
PlayerInputRumbleExample.cs
using System.Collections;
using System.Linq;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Haptics;
[RequireComponent(typeof(PlayerInput))]
public class PlayerInputRumbleExample : MonoBehaviour
{
private IEnumerator Start()
{
// PlayerInputインスタンスを取得
var playerInput = GetComponent<PlayerInput>();
// PlayerInputから振動可能なデバイス取得
// playerInput.devicesは現在選択されているスキームのデバイス一覧であることに注意
if (playerInput.devices.FirstOrDefault(x => x is IDualMotorRumble) is not IDualMotorRumble gamepad)
{
Debug.Log("デバイス未接続");
yield break;
}
// 振動
Debug.Log("コントローラ振動開始");
gamepad.SetMotorSpeeds(1.0f, 0.0f);
yield return new WaitForSeconds(1.0f);
gamepad.SetMotorSpeeds(0.0f, 1.0f);
yield return new WaitForSeconds(1.0f);
gamepad.SetMotorSpeeds(0.0f, 0.0f);
Debug.Log("コントローラ振動停止");
}
}
PlayerInputRumbleExample.csという名前で保存し、PlayerInputコンポーネントがアタッチされているゲームオブジェクトにアタッチすると機能するようになります。
スキームを設定した場合、サンプルスクリプトではゲーム起動時に、選択中スキームのデバイスを取得するため、Player InputのDefault SchemeをGamepadにしておく必要があります。(InputActionAsset側でもSchemeを正しくセットしておく必要があります)
ゲームパッドを接続した状態でゲームを実行すると、左右モーターを振動させることができます
次の部分で振動可能なデバイスを取得しています。
if (playerInput.devices.FirstOrDefault(x => x is IDualMotorRumble) is not IDualMotorRumble gamepad)
SetMotorSpeeds()メソッドは、IDualMotorRumbleインタフェースのメソッドを実装したもの。デバイスをIDualMotorRumbleにキャストしています。
キャストできるデバイスがあれば、振動させる処理に移行します。
gamepad.SetMotorSpeeds(1.0f, 0.0f);
yield return new WaitForSeconds(1.0f);
gamepad.SetMotorSpeeds(0.0f, 1.0f);
yield return new WaitForSeconds(1.0f);
gamepad.SetMotorSpeeds(0.0f, 0.0f);