Controlling with a Gamepad (Input System Package Version)
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.
Xbox | PlayStation | 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 left
down
right
up
properties 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 leftTrigger
class 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();
}
}
leftStick
rightStick
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.