Operation with a joystick (Input System packaged version)

Page update date :
Page creation date :

Verification environment

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

Prerequisites for this tip

The following settings are pre-configured as a prerequisite for the explanation of these tips.

About XInput and DirectInput

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

In Joystick this program, we are dealing with a class, but it can only handle controllers that support "DirectInput". To use a controller that supports "XInput", you need to use a different Gamepad class.

"DirectInput" is an old connection format, and the definition of buttons 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. Since "DirectInput" defines buttons as "1", "2", and "3", game creators must create a system that allows the game and controller button correspondence to be set appropriately.

"XInput" is defined as the next generation of "DirectInput" and has predefined A and B buttons, triggers, sticks, etc. Therefore, the shape of the controller can only be used, which is almost fixed. Since the definition of buttons is well defined, game creators can create games that match the controller without worrying about the placement of buttons. An increasing number of recent game controllers are only compatible with "XInput".

About Joysticks

As mentioned above, there is no definition of the button, so in order to actually use it, it is necessary to add troublesome processes such as assigning game operations while examining the information of each button. I don't think you need to use DirectInput in a new game because it's old, but keep in mind that if you really want to support it, your program can be complicated.

This sample is basically limited to obtaining information on the listed buttons. name In fact, you need to check and assign operations.

Joystick Information Acquisition

Place a text object to display information about each button on the joystick.

Create a script. The name is arbitrary, but in this case JoystickInfo , it is .

The script looks like this: The information obtained varies depending on the type of controller. It is very difficult to program for each controller, so I just enumerate all the buttons and get the button type and press information.

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

public class JoystickInfo : 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 joystick = Joystick.current;
    if (joystick == null)
    {
      Debug.Log("ジョイスティックがありません。");
      TextObject.text = "";
      return;
    }

    Builder.Clear();

    // ジョイスティックの情報取得
    Builder.AppendLine($"deviceId:{joystick.deviceId}");
    Builder.AppendLine($"name:{joystick.name}");
    Builder.AppendLine($"displayName:{joystick.displayName}");

    // ジョイスティックにはボタンの大部分が定義されていないので
    // 基本的には allControls で列挙して入力の種類と値を確認していく
    foreach (var key in joystick.allControls)
    {
      if (key is StickControl stick)
      {
        if (stick.up.isPressed) Builder.AppendLine($"{key.name} Up");
        if (stick.down.isPressed) Builder.AppendLine($"{key.name} Down");
        if (stick.left.isPressed) Builder.AppendLine($"{key.name} Left");
        if (stick.right.isPressed) Builder.AppendLine($"{key.name} Right");

        var value = stick.ReadValue();
        if (value.magnitude > 0f)
        {
          Builder.AppendLine($"{key.name}:{value.normalized * value.magnitude}");
        }
      }
      else if (key is Vector2Control vec2)
      {
        var value = vec2.ReadValue();
        if (value.magnitude > 0f)
        {
          Builder.AppendLine($"{key.name}:{value.normalized * value.magnitude}");
        }
        if (vec2.x.ReadValue() != 0f)
        {
          Builder.AppendLine($"{key.name}.x:{vec2.x.ReadValue()}");
        }
        if (vec2.y.ReadValue() != 0f)
        {
          Builder.AppendLine($"{key.name}.x:{vec2.y.ReadValue()}");
        }
      }
      else if (key is ButtonControl button)
      {
        if (button.isPressed) Builder.AppendLine($"{key.name} isPress");
        var value = button.ReadValue();
        if (value != 0f)
        {
          Builder.AppendLine($"{key.name}:{value}");
        }
      }
      else if (key is AxisControl axis)
      {
        if (axis.IsPressed()) Builder.AppendLine($"{key.name} isPress");

        var value = axis.ReadValue();
        if (value != 0f)
        {
          Builder.AppendLine($"{key.name}:{value}");
        }
      }
      else
      {
        Builder.AppendLine($"Type={key.GetType()}");
      }
    }

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

You can get information Joystick.current about the connected joystick in . Joystick After that, we will get each information from the class.

Joystick As you can see from the class, stick trigger there are definitions such as and , but there are no definitions such as the A button or the start button. Therefore, you should use the Properties to enumerate all buttons, sticks,allControls and find out the button type and press information.

Once the script is saved, EventSystem attach it to and set a text object for displaying information.

Try running the game with a controller that supports DirectInput. Each piece of information can be retrieved.

Depending on the controller, you may not get the value as intended when you press a stick, arrow key, etc. Since the buttons are not defined in this way, it is difficult to obtain accurate press information for each button. In addition, you can see that it is quite difficult to fully support the joystick, such as the arrangement of the buttons differs depending on the controller.

If the game is to support joysticks, it would be desirable to have a setting screen like a key config so that each user can customize the button layout of the controller they have.

How to get information for multiple joysticks

Information about Joystick.all all connected joysticks can be obtained in . ReadOnlyArray It foreach can be enumerated in and so on.

Since each value is Joystick a class, you can get joystick information as in the previous program.