使用操纵杆操作(输入系统封装版本)
验证环境
- 窗户
-
- 窗户11
- Unity 编辑器
-
- 2020.3.25f1
- 输入系统包
-
- 1.2.0
此提示的先决条件
以下设置已预先配置为解释这些提示的先决条件。
关于 XInput 和 DirectInput
虽然它仅限于 Windows,但游戏控制器有两种连接格式:“DirectInput”和“XInput”。 此处的“Joystick”对应于“DirectInput”。
在这个程序中 Joystick
,我们正在处理一个类,但它只能处理支持“DirectInput”的控制器。
若要使用支持“XInput”的控制器,需要使用不同的 Gamepad
类。
“DirectInput”是一种旧的连接格式,按钮的定义比较模糊,可以处理具有特殊形状的控制器。 然而,最近,“XInput”已成为主流,不支持“DirectInput”的控制器数量正在增加。 由于“DirectInput”将按钮定义为“1”、“2”和“3”,因此游戏创建者必须创建一个系统,以允许适当设置游戏和控制器按钮的对应关系。
“XInput”被定义为下一代“DirectInput”,具有预定义的 A 和 B 按钮、触发器、摇杆等。 因此,控制器的形状只能使用,这几乎是固定的。 由于按钮的定义定义明确,游戏创建者可以创建与控制器匹配的游戏,而无需担心按钮的位置。 最近越来越多的游戏控制器仅与“XInput”兼容。
关于操纵杆
如上所述,按钮没有定义,因此为了实际使用它,有必要在检查每个按钮的信息的同时添加麻烦的过程,例如分配游戏操作。 我不认为你需要在新游戏中使用 DirectInput,因为它很旧,但请记住,如果你真的想支持它,你的程序可能会很复杂。
此示例基本上仅限于获取有关所列按钮的信息。
name
实际上,您需要检查和分配操作。
操纵杆信息采集
放置一个文本对象以显示有关操纵杆上每个按钮的信息。
创建脚本。 名称是任意的,但在本例 JoystickInfo
中,它是 。
脚本如下所示: 获得的信息因控制器的类型而异。 为每个控制器编程非常困难,所以我只需枚举所有按钮并获取按钮类型和按下信息。
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();
}
}
您可以在 中获取有关连接的操纵杆的信息 Joystick.current
。
Joystick
之后,我们将从班级中获取每个信息。
Joystick
从类中可以看出,有 和 等定义, stick
trigger
但没有 A 按钮或开始按钮等定义。
因此,您应该使用“属性”来枚举所有按钮、摇杆,allControls
并找出按钮类型和新闻信息。
保存脚本后, EventSystem
将其附加到文本对象并设置用于显示信息的文本对象。
尝试使用支持 DirectInput 的控制器运行游戏。 可以检索每条信息。
根据控制器的不同,当您按下摇杆、箭头键等时,可能无法按预期获得值。 由于按钮不是以这种方式定义的,因此很难获得每个按钮的准确按下信息。 此外,您可以看到完全支持操纵杆非常困难,例如按钮的排列因控制器而异。
如果游戏要支持操纵杆,最好有一个像按键配置一样的设置屏幕,以便每个用户都可以自定义他们拥有的控制器的按钮布局。
如何获取多个操纵杆的信息
有关 Joystick.all
所有连接的操纵杆的信息,请参见 。
ReadOnlyArray
它可以 foreach
枚举在等中。
由于每个值都是一个 Joystick
类,因此您可以像在前面的程序中一样获取操纵杆信息。