使用操縱桿操作(輸入系統封裝版本)

更新頁 :
頁面創建日期 :

驗證環境

窗戶
  • 窗戶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.currentJoystick 之後,我們將從班級中獲取每個資訊。

Joystick 從類中可以看出,有和 等定義, stick trigger 但沒有 A 按鈕或開始按鈕等定義。 因此,您應該使用「屬性」來枚舉所有按鈕、搖桿,allControls 並找出按鈕類型和新聞資訊。

保存文稿后, EventSystem 將其附加到文本物件並設置用於顯示資訊的文字物件。

嘗試使用支援 DirectInput 的控制器運行遊戲。 可以檢索每條資訊。

根據控制器的不同,當您按下搖桿、箭頭鍵等時,可能無法按預期獲得值。 由於按鈕不是以這種方式定義的,因此很難獲得每個按鈕的準確按下資訊。 此外,您可以看到完全支援操縱桿非常困難,例如按鈕的排列因控制器而異。

如果遊戲要支援操縱桿,最好有一個像按鍵配置一樣的設置螢幕,以便每個使用者都可以自定義他們擁有的控制器的按鈕佈局。

如何獲取多個操縱桿的資訊

有關 Joystick.all 所有連線的操縱桿的資訊,請參見 。 ReadOnlyArray 它可以 foreach 枚舉在等中。

由於每個值都是一個 Joystick 類,因此您可以像在前面的程式中一樣獲取操縱桿資訊。