Controlling with a Gamepad (Input System Package Version)

Page update date :
Page creation date :

Verification environment

Windows
  • Windows 11
Unity Editor
  • 2020.3.25f1
Input System Package
  • 1.2.0

Prerequisites for this tip

The following settings have been made in advance as a premise for the description of this tip.

About XInput and DirectInput

Although it is limited to Windows, there are two connection formats for game controllers: DirectInput and XInput. Here, "Gamepad" corresponds to "XInput".

This Gamepad program deals with classes, but this can only handle controllers that support "XInput". To use a controller that supports DirectInput, you need to use a different Joystick class.

"DirectInput" is an old connection format and the definition of the button is relatively ambiguous, and it can handle controllers with special shapes. However, recently, "XInput" has become mainstream, and the number of controllers that do not support "DirectInput" is increasing. "DirectInput" has button definitions such as "1", "2", and "3", so game creators must create a button correspondence between the game and the controller so that they can be set appropriately.

XInput is defined as the next generation of DirectInput and includes predefined A and B buttons, triggers, sticks, etc. Therefore, only a fixed shape of the controller can be used, Since the definition of buttons is well defined, game creators can create games that suit the controller without worrying about the placement of buttons. Recent game controllers that only support "XInput" are increasing.

Determine if a button is being pressed

You can determine whether a button is pressed or not by properties as well as xxxxxxxx.isPressed keyboard and mouse. Here, I would like to display the type of button I am pressing in the text.

First, place a display text object.

Create a script for the verdict. The file name is arbitrary, but here GamepadButtons it is .

The script looks like this:

using System.Text;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class GamepadButtons : MonoBehaviour
{
  /// <summary>情報を表示させるテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  StringBuilder Builder = new StringBuilder();

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    if (TextObject == null)
    {
      Debug.Log($"{nameof(TextObject)} が null です。");
      return;
    }

    // 1つ目のゲームパッドの情報を取得
    var gamepad = Gamepad.current;
    if (gamepad == null)
    {
      Debug.Log("ゲームパッドがありません。");
      TextObject.text = "";
      return;
    }

    Builder.Clear();

    // ボタンを押している間は xxxxxxxx.isPressed が true を返します

    // B ボタンや East ボタン、○ボタンは読み方が違うだけで同じボタンです
    // これは PlayStation や Xbox, Switch などでボタンの読み方が違うためです
    if (gamepad.aButton.isPressed) Builder.AppendLine($"A");
    if (gamepad.bButton.isPressed) Builder.AppendLine($"B");
    if (gamepad.xButton.isPressed) Builder.AppendLine($"X");
    if (gamepad.yButton.isPressed) Builder.AppendLine($"Y");

    if (gamepad.buttonEast.isPressed) Builder.AppendLine($"East");
    if (gamepad.buttonWest.isPressed) Builder.AppendLine($"West");
    if (gamepad.buttonNorth.isPressed) Builder.AppendLine($"North");
    if (gamepad.buttonSouth.isPressed) Builder.AppendLine($"South");

    if (gamepad.circleButton.isPressed) Builder.AppendLine($"Circle");
    if (gamepad.crossButton.isPressed) Builder.AppendLine($"Cross");
    if (gamepad.triangleButton.isPressed) Builder.AppendLine($"Triangle");
    if (gamepad.squareButton.isPressed) Builder.AppendLine($"Square");

    // コントローラーの中央にあるスタートボタン、セレクトボタン、メニューボタン、ビューボタンなどに該当します。
    if (gamepad.startButton.isPressed) Builder.AppendLine($"Start");
    if (gamepad.selectButton.isPressed) Builder.AppendLine($"Select");

    // 左と右のスティックをまっすぐ押し込んだかどうかを判定します
    if (gamepad.leftStickButton.isPressed) Builder.AppendLine($"LeftStickButton");
    if (gamepad.rightStickButton.isPressed) Builder.AppendLine($"RightStickButton");

    // 左上と右上にあるボタン。PlayStation だと L1 や R1 に該当します
    if (gamepad.leftShoulder.isPressed) Builder.AppendLine($"LeftShoulder");
    if (gamepad.rightShoulder.isPressed) Builder.AppendLine($"RightShoulder");

    // 押しているボタン一覧をテキストで表示
    TextObject.text = Builder.ToString();
  }
}

After EventSystem you save the script, attach it to and configure the display text object.

Try running the game and see if each button responds.

By the way, the following buttons are defined as the same button, although multiple buttons are prepared because they are read differently depending on the game console. In each of the above programs, a judgment process is included, so when you press the button, three buttons are displayed.

XboxPlayStation and more
bButton circleButton buttonEast
aButton crossButton buttonSouth
xButton squareButton buttonWest
yButton triangleButton buttonNorth

What can be judged as a button is as follows.

  • A button, × button, down button
  • B button, ○ button, right button
  • X Button, □ Button, Left Button
  • Y button, Down Arrow button, Up button
  • Start button, Menu button
  • Select Button, View Button
  • Left shoulder button, L1 button
  • Right shoulder button, R1 button
  • Left stick button
  • Right stick button

Determine if the button is pressed

The judgment at the moment of press can be determined by the properties as with xxxxxxxx.wasPressedThisFrame the keyboard and mouse. Returns the value of the moment true it is pressed, and returns even if false it is pressed and held thereafter.

Let's display the button pressed as text as an operation check. Place a text object for display.

The file name of the script can be anything, but here GamepadButtonsOneFrame it is .

The script looks like this: For simplicity, only 4 buttons are judged.

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class GamepadButtonsOneFrame : MonoBehaviour
{
  /// <summary>情報を表示させるテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    if (TextObject == null)
    {
      Debug.Log($"{nameof(TextObject)} が null です。");
      return;
    }

    // 1つ目のゲームパッドの情報を取得
    var gamepad = Gamepad.current;
    if (gamepad == null)
    {
      Debug.Log("ゲームパッドがありません。");
      TextObject.text = "";
      return;
    }

    // ボタンが押された瞬間かどうかを判定
    if (gamepad.aButton.wasPressedThisFrame) TextObject.text += "A";
    if (gamepad.bButton.wasPressedThisFrame) TextObject.text += "B";
    if (gamepad.xButton.wasPressedThisFrame) TextObject.text += "X";
    if (gamepad.yButton.wasPressedThisFrame) TextObject.text += "Y";
  }
}

After EventSystem saving the script, attach it to and set a text object for display.

Try running the game and pressing the button. I think the button you pressed will be added. You can also see that holding down the button doesn't add any text.

Determine if the moment the button is released

There is no sample, but you can determine if it is wasPressedThisFrame the moment you release it by using a property instead of wasReleasedThisFrame a property.

Determine when you press the arrow keys

Determines the press of the DPAD. Depending on the game console, it will fly with the arrow keys and the D-pad, but both are treated as the same. The DPAD basically only determines whether you are pushing in that direction or not. There is no judgment like "pushing a little" like a stick.

Places a text object to display a decision whether it is pressed or not as an operation check.

Create a script. The file name is arbitrary, but here GamepadDpad it is .

The script looks like this:

using System.Text;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class GamepadDpad : MonoBehaviour
{
  /// <summary>情報を表示させるテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  StringBuilder Builder = new StringBuilder();

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    if (TextObject == null)
    {
      Debug.Log($"{nameof(TextObject)} が null です。");
      return;
    }

    // 1つ目のゲームパッドの情報を取得
    var gamepad = Gamepad.current;
    if (gamepad == null)
    {
      Debug.Log("ゲームパッドがありません。");
      TextObject.text = "";
      return;
    }

    Builder.Clear();

    // Dpad の押下情報を Vector2 として取得するパターン
    var value = gamepad.dpad.ReadValue();
    Builder.Append($"(x:{value.x}, y:{value.y})");

    // Dpad の各方向のボタンを押しているかどうかの判定
    if (gamepad.dpad.left.isPressed) Builder.Append(" left");
    if (gamepad.dpad.right.isPressed) Builder.Append(" right");
    if (gamepad.dpad.up.isPressed) Builder.Append(" up");
    if (gamepad.dpad.down.isPressed) Builder.Append(" down");

    // Dpad の情報をテキストで表示
    TextObject.text = Builder.ToString();
  }
}

You can get DPAD information Gamepad.dpad at .

DPAD has leftdown rightupproperties for each direction, and you can determine whether it is pressed or not by the property etc. isPressed

DpadControl.ReadValue You can also use the method to get the state Vector2 of the press in . If nothing is pressed (0, 0), if left is pressed (-1, 0), and so on.

After EventSystem saving the script, attach it to and set a text object for display.

Try running the game and interacting with the DPAD.

Vector2 By the way, is in a normalized state, so when you press diagonally, it is obtained as a number such as (0.7071, 0.7071) instead of (1, 1).

Determine trigger presses

Xbox controllers have buttons called triggers on the left and right. On PlayStation, it corresponds to L2R2. This button is different from a normal button, and you can get the amount you are pressing in 0.0~1.0. Some other controllers are equipped with names other than triggers, but in older controllers, etc., they may simply be placed as buttons, in which case the judgment of pressing is handled only as 0, 1.

Here, I would like to check the amount of trigger presses. Places a text object for display on the Canvas.

Create a script. Since it will be used elsewhere, we will name it here GamepadReadValue .

The script looks like this:

using System.Text;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class GamepadReadValue : MonoBehaviour
{
  /// <summary>情報を表示させるテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  StringBuilder Builder = new StringBuilder();

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    if (TextObject == null)
    {
      Debug.Log($"{nameof(TextObject)} が null です。");
      return;
    }

    // 1つ目のゲームパッドの情報を取得
    var gamepad = Gamepad.current;
    if (gamepad == null)
    {
      Debug.Log("ゲームパッドがありません。");
      TextObject.text = "";
      return;
    }

    Builder.Clear();

    // トリガーの押下量を取得
    Builder.AppendLine($"LeftTrigger:{gamepad.leftTrigger.ReadValue()}");
    Builder.AppendLine($"RightTrigger:{gamepad.rightTrigger.ReadValue()}");

    // 情報をテキストで表示
    TextObject.text = Builder.ToString();
  }
}

Gamepad Each leftTriggerclass has a property and rightTrigger ReadValue you can get the amount of presses in the range of 0.0~1.0 by calling the method. Triggers can also be treated as buttons, so isPressed you can also judge such as. isPressed true By the way, the amount of becomes ReadValue is based on 0.5.

After saving the script, EventSystem attach it to and set a text object for display.

Try running the game and moving the trigger.

Determine stick information

The stick can get the information of the left stick and the right stick respectively, and you can get the amount of how much the stick is pushed down in which direction. Of course, if you don't have a stick on your controller, you won't be able to get this information.

Stick information can be retrieved with , Gamepad.rightStick respectivelyGamepad.leftStick.

For the operation confirmation script, we will divert the script used earlier to get the trigger.

// 省略

public class GamepadReadValue : MonoBehaviour
{
  // 省略

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    // 省略

    // トリガーの押下量を取得
    Builder.AppendLine($"LeftTrigger:{gamepad.leftTrigger.ReadValue()}");
    Builder.AppendLine($"RightTrigger:{gamepad.rightTrigger.ReadValue()}");

    // スティックの入力を取得
    var leftStickValue = gamepad.leftStick.ReadValue();
    Builder.AppendLine($"LeftStick:{leftStickValue.normalized * leftStickValue.magnitude}");
    var rightStickValue = gamepad.rightStick.ReadValue();
    Builder.AppendLine($"RightStick:{rightStickValue.normalized * rightStickValue.magnitude}");

    // 情報をテキストで表示
    TextObject.text = Builder.ToString();
  }
}

leftStickrightStick You can get the press information by calling the Vector2 method from ReadValue or . Vector2 So you can get how x y much you are pressing on the X axis and Y axis by and properties, If you want to get the direction you are pressing, you can get it in the property, and if you magnitude want to get the amount you are pressing, you normalized can get it in the property.

Try to actually move the game and operate the stick.

Get gamepad information

You can get the ID, name, etc. from the connected gamepad. For example, refer to to to identify name the type of controller that is connected, or You can refer to for which deviceId gamepad to associate with when multiple gamepads are connected.

Here, we will display the information in the text to check the operation.

The script name is arbitrary, but here GamepadInfo it is .

The script looks like this:

using System.Text;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class GamepadInfo : MonoBehaviour
{
  /// <summary>情報を表示させるテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  StringBuilder Builder = new StringBuilder();

  // 更新はフレームごとに1回呼び出されます
  void Update()
  {
    if (TextObject == null)
    {
      Debug.Log($"{nameof(TextObject)} が null です。");
      return;
    }

    // 1つ目のゲームパッドの情報を取得
    var gamepad = Gamepad.current;
    if (gamepad == null)
    {
      Debug.Log("ゲームパッドがありません。");
      TextObject.text = "";
      return;
    }

    Builder.Clear();

    // ゲームパッドの各情報を取得
    Builder.AppendLine($"deviceId:{gamepad.deviceId}");
    Builder.AppendLine($"name:{gamepad.name}");
    Builder.AppendLine($"displayName:{gamepad.displayName}");
    Builder.AppendLine($"shortDisplayName:{gamepad.shortDisplayName}");
    Builder.AppendLine($"path:{gamepad.path}");
    Builder.AppendLine($"layout:{gamepad.layout}");

    // 情報をテキストで表示
    TextObject.text = Builder.ToString();
  }
}

Gamepad You can get various information from the retrieved . Here are some excerpts.

After saving the script, EventSystem attach it to and set a text object for display.

Try running the game to see if the information appears.