使用游戏手柄进行控制(输入系统包版本)
验证环境
- 窗户
-
- 视窗 11
- 统一编辑器
-
- 2020.3.25f1
- 输入系统包
-
- 1.2.0
此提示的先决条件
作为此提示描述的前提,已预先进行了以下设置。
关于 XInput 和 DirectInput
虽然它仅限于Windows,但游戏控制器有两种连接格式:DirectInput和XInput。 在这里,“游戏手柄”对应于“XInput”。
该程序 Gamepad
处理类,但这只能处理支持“XInput”的控制器。
若要使用支持 DirectInput 的控制器,需要使用不同的 Joystick
类。
“DirectInput”是一种旧的连接格式,按钮的定义相对模糊,它可以处理具有特殊形状的控制器。 然而,最近,“XInput”已经成为主流,不支持“DirectInput”的控制器数量正在增加。 “DirectInput”具有“1”、“2”和“3”等按钮定义,因此游戏创建者必须在游戏和控制器之间创建按钮对应关系,以便可以正确设置它们。
XInput 被定义为下一代 DirectInput,包括预定义的 A 和 B 按钮、触发器、摇杆等。 因此,只能使用固定形状的控制器, 由于按钮的定义很好,游戏创建者可以创建适合控制器的游戏,而无需担心按钮的位置。 最近仅支持“XInput”的游戏控制器正在增加。
确定是否按下了按钮
您可以确定是否通过属性以及 xxxxxxxx.isPressed
键盘和鼠标按下按钮。
在这里,我想在文本中显示我按下的按钮类型。
首先,放置一个显示文本对象。
为判决创建脚本。 文件名是任意的,但这里是 GamepadButtons
.
脚本如下所示:
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();
}
}
保存脚本后 EventSystem
,将其附加到显示文本对象并对其进行配置。
尝试运行游戏,看看每个按钮是否响应。
顺便说一下,以下按钮被定义为同一个按钮,尽管准备了多个按钮,因为它们的读取方式因游戏机而异。 在上述每个程序中,都包含一个判断过程,因此当您按下按钮时,会显示三个按钮。
Xbox | PlayStation | 等 |
---|---|---|
b按钮 | 圆圈按钮 | 按钮东 |
a按钮 | 十字按钮 | 按钮南 |
x按钮 | 方形按钮 | 纽扣西 |
y按钮 | 三角形按钮 | 按钮北 |
可以判断为按钮的内容如下。
- 按钮、×按钮、向下按钮
- B 按钮、○ 按钮、右按钮
- X 按钮、□按钮、左按钮
- Y 按钮、向下箭头按钮、向上按钮
- “开始”按钮、“菜单”按钮
- “选择”按钮、“查看”按钮
- 左肩按钮,L1按钮
- 右肩按钮,R1按钮
- 左摇杆按钮
- 右摇杆按钮
确定是否按下按钮
按下时的判断可以由键盘和鼠标的属性 xxxxxxxx.wasPressedThisFrame
决定。
返回按下该时刻的值,即使此后按下并按住该值 true
也 false
返回。
让我们将按下的按钮显示为文本作为操作检查。 放置要显示的文本对象。
脚本的文件名可以是任何内容,但这里是 GamepadButtonsOneFrame
.
脚本如下所示: 为简单起见,仅判断 4 个按钮。
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";
}
}
保存脚本后 EventSystem
,将其附加到并设置要显示的文本对象。
尝试运行游戏并按下按钮。 我认为您按下的按钮将被添加。 您还可以看到按住按钮不会添加任何文本。
确定按钮是否松开的那一刻
没有示例,但你可以通过使用属性而不是wasReleasedThisFrame
属性来确定是否是wasPressedThisFrame
释放它的时刻。
确定何时按箭头键
确定 DPAD 的按下时间。 根据游戏机的不同,它将与箭头键和方向键一起飞行,但两者都被视为相同。 DPAD基本上只决定你是否朝着那个方向推动。 没有像棍子一样“推一点”这样的判断。
放置文本对象以显示是否按下该对象作为操作检查的决定。
创建脚本。 文件名是任意的,但这里是 GamepadDpad
.
脚本如下所示:
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();
}
}
您可以在 上获取 DPAD 信息 Gamepad.dpad
。
DPAD 具有left
up
down
right
每个方向的属性,您可以确定它是否被属性等按下。 isPressed
DpadControl.ReadValue
您还可以使用该方法在 中获取压力机的状态Vector2
。 如果不按任何内容 (0, 0),如果按左键 (-1, 0),依此类推。
保存脚本后 EventSystem
,将其附加到并设置要显示的文本对象。
尝试运行游戏并与 DPAD 交互。
Vector2
顺便说一下,处于规范化状态,因此当您对角线按下时,它以数字形式获得,例如 (0.7071, 0.7071) 而不是 (1, 1)。
确定触发按下
Xbox 控制器的左侧和右侧都有称为触发器的按钮。 在PlayStation上,它对应于L2R2。 此按钮与普通按钮不同,您可以在0.0~1.0中获取您按下的量。 其他一些控制器配备了触发器以外的名称,但在较旧的控制器等中,它们可能只是作为按钮放置,在这种情况下,按下的判断仅作为 0、1 处理。
在这里,我想检查扳机按下的次数。 放置要在画布上显示的文本对象。
创建脚本。 由于它将在其他地方使用,因此我们将在此处 GamepadReadValue
命名 。
脚本如下所示:
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
每个leftTrigger
类都有一个属性,rightTrigger
ReadValue
你可以通过调用该方法得到 0.0~1.0 范围内的按压量。
触发器也可以被视为按钮,因此isPressed
您也可以判断诸如。
isPressed
true
顺便说一下,成为ReadValue
的数量是基于 0.5。
保存脚本后, EventSystem
将其附加到并设置要显示的文本对象。
尝试运行游戏并移动扳机。
确定摇杆信息
摇杆可以分别获取左摇杆和右摇杆的信息,并且可以得到摇杆在哪个方向向下推多少的量。 当然,如果您的控制器上没有摇杆,您将无法获得此信息。
棍子信息可以分别Gamepad.leftStick
使用 检索。 Gamepad.rightStick
对于操作确认脚本,我们将转移之前用于获取触发器的脚本。
// 省略
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
可以通过从 Vector2
或 调用ReadValue
方法获取新闻信息。
Vector2
因此,您可以获得在 X 轴和 Y 轴上按下了多少x
y
和属性,
如果你想得到你按下的方向,你可以在属性中得到它,如果你想magnitude
得到你正在按下的数量,你可以在normalized
属性中得到它。
尝试实际移动游戏并操作摇杆。
获取游戏手柄信息
您可以从连接的游戏手柄中获取ID,名称等。
例如,请参阅 以标识 name
所连接的控制器的类型,或
您可以参考连接多个游戏手柄时要与哪个 deviceId
游戏手柄关联。
在这里,我们将在文本中显示信息以检查操作。
脚本名称是任意的,但这里是 GamepadInfo
.
脚本如下所示:
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
您可以从检索到的. 以下是一些摘录。
保存脚本后, EventSystem
将其附加到并设置要显示的文本对象。
尝试运行游戏以查看信息是否显示。