Ovládání pomocí joysticku (verze v balení se vstupním systémem)

Stránky aktualizovány :
Datum vytvoření stránky :

Ověřovací prostředí

Windows
  • Systém Windows 11
Unity Editor
  • 2020.3.25f1
Balíčky vstupního systému
  • 1.2.0

Předpoklady pro tento tip

Následující nastavení jsou předem nakonfigurovaná jako předpoklad pro vysvětlení těchto tipů.

O XInput a DirectInput

Ačkoli je omezen na Windows, existují dva formáty připojení pro herní ovladače: "DirectInput" a "XInput". "Joystick" zde odpovídá "DirectInput".

V Joystick tomto programu máme co do činění s třídou, ale ta může pracovat pouze s kontrolery, které podporují "DirectInput". Chcete-li použít kontroler, který podporuje "XInput", musíte použít jinou Gamepad třídu.

"DirectInput" je starý formát připojení a definice tlačítek je poměrně nejednoznačná a zvládne ovladače se speciálními tvary. V poslední době se však "XInput" stal mainstreamem a počet ovladačů, které nepodporují "DirectInput", se zvyšuje. Vzhledem k tomu, že "DirectInput" definuje tlačítka jako "1", "2" a "3", musí tvůrci her vytvořit systém, který umožní správné nastavení shody tlačítek hry a ovladače.

"XInput" je definován jako nová generace "DirectInput" a má předdefinovaná tlačítka A a B, spouštěče, páčky atd. Proto lze použít pouze tvar ovladače, který je téměř pevný. Vzhledem k tomu, že definice tlačítek je dobře definovaná, mohou tvůrci her vytvářet hry, které odpovídají ovladači, aniž by se museli starat o umístění tlačítek. Stále více současných herních ovladačů je kompatibilní pouze s "XInput".

O joystickech

Jak již bylo zmíněno výše, neexistuje žádná definice tlačítka, takže aby bylo možné jej skutečně používat, je nutné přidat problematické procesy, jako je přiřazování herních operací při zkoumání informací o každém tlačítku. Nemyslím si, že potřebujete používat DirectInput v nové hře, protože je stará, ale mějte na paměti, že pokud ji opravdu chcete podporovat, váš program může být komplikovaný.

Tato ukázka je v podstatě omezena na získávání informací o uvedených tlačítkách. name Ve skutečnosti musíte zkontrolovat a přiřadit operace.

Získávání informací joystickem

Umístěte textový objekt, aby se zobrazily informace o každém tlačítku na joysticku.

Vytvořte skript. Název je libovolný, ale v tomto případě JoystickInfo je .

Skript vypadá takto: Získané informace se liší v závislosti na typu ovladače. Je velmi obtížné naprogramovat pro každý ovladač, takže jen vyjmenuji všechna tlačítka a získám informace o typu tlačítka a stisknutí.

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

Informace Joystick.current o připojeném joysticku můžete získat v . Joystick Poté získáme jednotlivé informace ze třídy.

Joystick Jak můžete vidět ze třídy, existují definice jako a , ale neexistují žádné definice, stick trigger jako je tlačítko A nebo tlačítko Start. Proto byste měli použít Vlastnosti k vytvoření výčtu všech tlačítek, páčekallControls a zjištění typu tlačítka a informací o stisknutí.

Jakmile je skript uložen EventSystem , připojte jej k textovému objektu a nastavte jej pro zobrazení informací.

Zkuste hru spustit s ovladačem, který podporuje DirectInput. Každou informaci lze načíst.

V závislosti na ovladači se může stát, že při stisknutí páčky, klávesy se šipkou atd. nezískáte hodnotu tak, jak jste zamýšleli. Vzhledem k tomu, že tlačítka nejsou definována tímto způsobem, je obtížné získat přesné informace o stisknutí každého tlačítka. Kromě toho můžete vidět, že je poměrně obtížné plně podporovat joystick, například uspořádání tlačítek se liší v závislosti na ovladači.

Pokud má hra podporovat joysticky, bylo by žádoucí mít obrazovku nastavení jako konfiguraci kláves, aby si každý uživatel mohl přizpůsobit rozložení tlačítek ovladače, který má.

Jak získat informace pro více joysticků

Informace o Joystick.all všech připojených joystickech lze získat v . ReadOnlyArray Může foreach být vyjmenován v a tak dále.

Vzhledem k tomu, že každá hodnota je Joystick třída, můžete získat informace joysticku jako v předchozím programu.