Mengawal dengan Gamepad (Versi Pakej Sistem Input)

Laman dikemaskini :
Tarikh penciptaan halaman :

Persekitaran pengesahan

Windows
  • Windows 11
Penyunting Perpaduan
  • 2020.3.25f1
Pakej Sistem Input
  • 1.2.0

Prasyarat untuk petua ini

Tetapan berikut telah dibuat terlebih dahulu sebagai premis untuk penerangan petua ini.

Mengenai XInput dan DirectInput

Walaupun terhad kepada Windows, terdapat dua format sambungan untuk pengawal permainan: DirectInput dan XInput. Di sini, "Gamepad" sepadan dengan "XInput".

Program ini berkaitan dengan kelas, tetapi ini Gamepad hanya boleh mengendalikan pengawal yang menyokong "XInput". Untuk menggunakan pengawal yang menyokong DirectInput, anda perlu menggunakan kelas yang berbeza Joystick .

"DirectInput" adalah format sambungan lama dan definisi butang agak samar-samar, dan ia boleh mengendalikan pengawal dengan bentuk khas. Walau bagaimanapun, baru-baru ini, "XInput" telah menjadi arus perdana, dan bilangan pengawal yang tidak menyokong "DirectInput" semakin meningkat. "DirectInput" mempunyai definisi butang seperti "1", "2", dan "3", jadi pencipta permainan mesti membuat surat-menyurat butang antara permainan dan pengawal supaya mereka dapat ditetapkan dengan sewajarnya.

XInput ditakrifkan sebagai generasi seterusnya DirectInput dan termasuk butang A dan B yang telah ditetapkan, pencetus, tongkat, dll. Oleh itu, hanya bentuk pengawal tetap boleh digunakan, Oleh kerana definisi butang ditakrifkan dengan baik, pencipta permainan boleh membuat permainan yang sesuai dengan pengawal tanpa perlu risau tentang penempatan butang. Pengawal permainan terkini yang hanya menyokong "XInput" semakin meningkat.

Tentukan sama ada butang sedang ditekan

Anda boleh menentukan sama ada butang ditekan atau tidak dengan sifat serta xxxxxxxx.isPressed papan kekunci dan tetikus. Di sini, saya ingin memaparkan jenis butang yang saya tekan dalam teks.

Mula-mula, letakkan objek teks paparan.

Buat skrip untuk keputusan itu. Nama fail sewenang-wenangnya, tetapi di sini GamepadButtons ia adalah .

Skrip kelihatan seperti ini:

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();
  }
}

Selepas EventSystem anda menyimpan skrip, lampirkannya dan konfigurasikan objek teks paparan.

Cuba jalankan permainan dan lihat sama ada setiap butang bertindak balas.

Dengan cara ini, butang berikut ditakrifkan sebagai butang yang sama, walaupun berbilang butang disediakan kerana ia dibaca secara berbeza bergantung pada konsol permainan. Dalam setiap program di atas, proses penghakiman dimasukkan, jadi apabila anda menekan butang, tiga butang dipaparkan.

Xbox PlayStation dan banyak lagi
bButton bulatanButton butangEast
aButton crossButton butangSouth
xButton kuasa duaButton buttonWest
yButton segi tigaButton butangNorth

Apa yang boleh dinilai sebagai butang adalah seperti berikut.

  • Butang, butang ×, butang bawah
  • Butang B, butang ○, butang kanan
  • Butang X, butang □, butang kiri
  • Butang Y, butang Anak Panah Ke Bawah, butang Atas
  • Butang Mula, butang Menu
  • Butang Pilih, butang Pandangan
  • Butang bahu kiri, butang L1
  • Butang bahu kanan, butang R1
  • Butang tongkat kiri
  • Butang tongkat kanan

Tentukan sama ada butang ditekan

Penghakiman pada masa akhbar boleh ditentukan oleh sifat-sifat seperti papan xxxxxxxx.wasPressedThisFrame kekunci dan tetikus. Mengembalikan nilai saat true ia ditekan dan dikembalikan walaupun false ia ditekan dan dipegang selepas itu.

Mari paparkan butang ditekan sebagai teks sebagai pemeriksaan operasi. Meletakkan objek teks untuk paparan.

Nama fail skrip boleh menjadi apa-apa, tetapi di sini GamepadButtonsOneFrame ia adalah .

Skrip kelihatan seperti ini: Untuk kesederhanaan, hanya 4 butang yang dinilai.

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";
  }
}

Selepas EventSystem menyimpan skrip, lampirkannya dan tetapkan objek teks untuk paparan.

Cuba jalankan permainan dan tekan butang. Saya rasa butang yang anda tekan akan ditambah. Anda juga boleh melihat bahawa menahan butang tidak menambah sebarang teks.

Tentukan sama ada saat butang dilepaskan

Tiada sampel, tetapi anda boleh menentukan sama ada ia adalah wasPressedThisFrame saat anda melepaskannya dengan menggunakan harta dan bukannya wasReleasedThisFrame harta.

Menentukan bila anda menekan kekunci anak panah

Menentukan akhbar DPAD. Bergantung pada konsol permainan, ia akan terbang dengan kekunci anak panah dan pad D, tetapi kedua-duanya dianggap sama. DPAD pada dasarnya hanya menentukan sama ada anda menolak ke arah itu atau tidak. Tidak ada penghakiman seperti "menolak sedikit" seperti tongkat.

Meletakkan objek teks untuk memaparkan keputusan sama ada ia ditekan atau tidak sebagai semakan operasi.

Buat skrip. Nama fail sewenang-wenangnya, tetapi di sini GamepadDpad ia adalah .

Skrip kelihatan seperti ini:

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();
  }
}

Anda boleh mendapatkan maklumat Gamepad.dpad DPAD di .

DPAD mempunyai leftupdown rightsifat untuk setiap arah, dan anda boleh menentukan sama ada ia ditekan atau tidak oleh harta dll. isPressed

DpadControl.ReadValue Anda juga boleh menggunakan kaedah untuk mendapatkan keadaan Vector2 akhbar di . Jika tiada apa yang ditekan (0, 0), jika dibiarkan ditekan (-1, 0), dan sebagainya.

Selepas EventSystem menyimpan skrip, lampirkannya dan tetapkan objek teks untuk paparan.

Cuba jalankan permainan dan berinteraksi dengan DPAD.

Vector2 Dengan cara ini, berada dalam keadaan normal, jadi apabila anda menekan secara menyerong, ia diperolehi sebagai nombor seperti (0.7071, 0.7071) dan bukannya (1, 1).

Tentukan tekanan pencetus

Pengawal Xbox mempunyai butang yang dipanggil pencetus di sebelah kiri dan kanan. Di PlayStation, ia sepadan dengan L2R2. Butang ini berbeza dengan butang biasa, dan anda boleh mendapatkan jumlah yang anda tekan dalam 0.0 ~ 1.0. Sesetengah pengawal lain dilengkapi dengan nama selain daripada pencetus, tetapi dalam pengawal yang lebih tua, dan lain-lain, mereka hanya boleh diletakkan sebagai butang, dalam hal ini penghakiman menekan dikendalikan hanya sebagai 0, 1.

Di sini, saya ingin menyemak jumlah akhbar pencetus. Meletakkan objek teks untuk dipaparkan pada Kanvas.

Buat skrip. Oleh kerana ia akan digunakan di tempat lain, kami akan menamakannya di sini GamepadReadValue .

Skrip kelihatan seperti ini:

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 Setiap leftTriggerkelas mempunyai harta dan rightTrigger ReadValue anda boleh mendapatkan jumlah akhbar dalam julat 0.0 ~ 1.0 dengan memanggil kaedah tersebut. Pencetus juga boleh dianggap sebagai butang, jadi isPressed anda juga boleh menilai seperti. isPressed true Dengan cara ini, jumlah menjadi ReadValue berdasarkan 0.5.

Selepas menyimpan skrip, EventSystem lampirkannya dan tetapkan objek teks untuk paparan.

Cuba jalankan permainan dan gerakkan pencetus.

Menentukan maklumat melekat

Batang boleh mendapatkan maklumat kayu kiri dan tongkat kanan masing-masing, dan anda boleh mendapatkan jumlah berapa banyak kayu ditolak ke bawah ke arah mana. Sudah tentu, jika anda tidak mempunyai tongkat pada pengawal anda, anda tidak akan dapat mendapatkan maklumat ini.

Maklumat kayu boleh diambil dengan , Gamepad.rightStick masing-masingGamepad.leftStick.

Untuk skrip pengesahan operasi, kami akan mengalihkan skrip yang digunakan sebelum ini untuk mendapatkan pencetus.

// 省略

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 Anda boleh mendapatkan maklumat akhbar dengan memanggil kaedah dari Vector2 ReadValue atau . Vector2 Jadi anda boleh mendapatkan berapa x y banyak yang anda tekan pada paksi X dan paksi Y mengikut dan sifat, Jika anda ingin mendapatkan arah yang anda tekan, anda boleh mendapatkannya di dalam hartanah, dan jika anda ingin mendapatkan jumlah yang anda tekan, anda magnitude normalized boleh mendapatkannya di dalam penginapan.

Cuba benar-benar menggerakkan permainan dan mengendalikan tongkat.

Dapatkan maklumat pad permainan

Anda boleh mendapatkan ID, nama, dsb. Sebagai contoh, rujuk untuk mengenal pasti name jenis pengawal yang disambungkan, atau Anda boleh merujuk kepada pad permainan mana yang deviceId hendak dikaitkan dengan apabila berbilang pad permainan disambungkan.

Di sini, kami akan memaparkan maklumat dalam teks untuk menyemak operasi.

Nama skrip sewenang-wenangnya, tetapi di sini GamepadInfo ia adalah .

Skrip kelihatan seperti ini:

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 Anda boleh mendapatkan pelbagai maklumat dari yang diambil . Berikut adalah beberapa petikan.

Selepas menyimpan skrip, EventSystem lampirkannya dan tetapkan objek teks untuk paparan.

Cuba jalankan permainan untuk melihat sama ada maklumat muncul.