使用遊戲手柄進行控制(輸入系統套件版本)

更新頁 :
頁面創建日期 :

驗證環境

窗戶
  • 視窗 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 ,將其附加到顯示文本物件並對其進行配置。

嘗試運行遊戲,看看每個按鈕是否回應。

順便說一下,以下按鈕被定義為同一個按鈕,儘管準備了多個按鈕,因為它們的讀取方式因遊戲機而異。 在上述每個程式中,都包含一個判斷過程,因此當您按下按鈕時,會顯示三個按鈕。

XboxPlayStation
b按鈕 圓圈按鈕 按鈕東
a按鈕 十字按鈕 按鈕南
x按鈕 方形按鈕 紐扣西
y按鈕 三角形按鈕 按鈕北

可以判斷為按鈕的內容如下。

  • 按鈕、×按鈕、向下按鈕
  • B 按鈕、○ 按鈕、右按鈕
  • X 按鈕、□按鈕、左按鈕
  • Y 按鈕、向下箭頭按鈕、向上按鈕
  • “開始”按鈕、“功能表”按鈕
  • “選擇”按鈕、“查看”按鈕
  • 左肩按鈕,L1按鈕
  • 右肩按鈕,R1按鈕
  • 左搖桿按鈕
  • 右搖桿按鈕

確定是否按下按鈕

按下時的判斷可以由鍵盤和滑鼠的屬性 xxxxxxxx.wasPressedThisFrame 決定。 返回按下該時刻的值,即使此後按下並按住該值 truefalse 返回。

讓我們將按下的按鈕顯示為文本作為操作檢查。 放置要顯示的文字物件。

文稿的檔案名可以是任何內容,但這裡是 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 具有leftrightupdown每個方向的屬性,您可以確定它是否被屬性等按下。 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類都有一個屬性,rightTriggerReadValue你可以通過調用該方法得到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();
  }
}

leftStickrightStick可以通過從 Vector2 或 調用ReadValue方法獲取新聞資訊。 Vector2因此,您可以獲得在 X 軸和 Y 軸上按下了多少xy和屬性, 如果你想得到你按下的方向,你可以在屬性中得到它,如果你想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 將其附加到並設置要顯示的文字物件。

嘗試運行遊戲以查看資訊是否顯示。