使用操縱桿操作(輸入系統封裝版本)
驗證環境
- 窗戶
-
- 窗戶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
類,因此您可以像在前面的程式中一樣獲取操縱桿資訊。