Styra med en gamepad (Input System Package Version)

Sidan uppdaterad :
Datum för skapande av sida :

Verifiering miljö

Windows
  • Fönster 11
Unity-redaktör
  • 2020.3.25F1
Paket för inmatningssystem
  • 1.2.0

Förutsättningar för det här tipset

Följande inställningar har gjorts i förväg som en förutsättning för beskrivningen av detta tips.

Om XInput och DirectInput

Även om det är begränsat till Windows finns det två anslutningsformat för spelkontroller: DirectInput och XInput. Här motsvarar "Gamepad" "XInput".

Detta Gamepad program behandlar klasser, men det kan bara hantera styrenheter som stöder "XInput". Om du vill använda en styrenhet som stöder DirectInput måste du använda en annan Joystick klass.

"DirectInput" är ett gammalt anslutningsformat och definitionen av knappen är relativt tvetydig och den kan hantera styrenheter med speciella former. Men nyligen har "XInput" blivit mainstream, och antalet kontroller som inte stöder "DirectInput" ökar. "DirectInput" har knappdefinitioner som "1", "2" och "3", så spelskapare måste skapa en knappkorrespondens mellan spelet och handkontrollen så att de kan ställas in på rätt sätt.

XInput definieras som nästa generation av DirectInput och innehåller fördefinierade A- och B-knappar, triggers, pinnar etc. Därför kan endast en fast form på regulatorn användas, Eftersom definitionen av knappar är väldefinierad kan spelskapare skapa spel som passar styrenheten utan att oroa sig för placeringen av knappar. Nya spelkontroller som bara stöder "XInput" ökar.

Kontrollera om du trycker på en knapp

Du kan bestämma om en knapp trycks in eller inte av egenskaper samt xxxxxxxx.isPressed tangentbord och mus. Här vill jag visa vilken typ av knapp jag trycker på i texten.

Montera först ett visningstextobjekt.

Skapa ett skript för domen. Filnamnet är godtyckligt, men här GamepadButtons är det .

Skriptet ser ut så här:

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

När du har EventSystem sparat skriptet kopplar du det till och konfigurerar visningstextobjektet.

Prova att köra spelet och se om varje knapp svarar.

Förresten definieras följande knappar som samma knapp, även om flera knappar är förberedda eftersom de läses olika beroende på spelkonsolen. I vart och ett av ovanstående program ingår en bedömningsprocess, så när du trycker på knappen visas tre knappar.

Xbox,PlayStation med mera
bKnapp circleButton buttonEast
aKnapp crossButton knappSöder
xKnapp squareButton buttonWest
yButton triangelKnapp buttonNorth

Vad som kan bedömas som en knapp är följande.

  • En knapp, × knapp, nedåtknapp
  • B-knapp, ○-knapp, höger knapp
  • X-knapp, □-knapp, vänster knapp
  • Y-knappen, nedåtpilen, upp-knappen
  • Start-knappen, menyknappen
  • Välj knapp, Visa-knapp
  • Vänster axelknapp, L1-knapp
  • Höger axelknapp, R1-knapp
  • Vänster styrspaksknapp
  • Höger spaksknapp

Kontrollera om knappen trycks in

Bedömningen vid presstillfället kan bestämmas av egenskaperna som med xxxxxxxx.wasPressedThisFrame tangentbordet och musen. Returnerar värdet för det ögonblick true den trycks ned och returnerar även om false den trycks ned och hålls ned därefter.

Låt oss visa knappen intryckt som text som en funktionskontroll. Placera ett textobjekt för visning.

Skriptets filnamn kan vara vad som helst, men här GamepadButtonsOneFrame är det .

Skriptet ser ut så här: För enkelhetens skull bedöms endast 4 knappar.

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

När du har sparat skriptet bifogar du EventSystem det till och ställer in ett textobjekt för visning.

Prova att köra spelet och trycka på knappen. Jag tror att knappen du tryckte på kommer att läggas till. Du kan också se att ingen text läggs till om du håller ned knappen.

Bestäm om det ögonblick som knappen släpps

Det finns inget exempel, men du kan avgöra om det är wasPressedThisFrame när du släpper det genom att använda en egenskap i stället för wasReleasedThisFrame en egenskap.

Bestämma när du trycker på piltangenterna

Bestämmer DPAD: s press. Beroende på spelkonsolen kommer den att flyga med piltangenterna och D-pad, men båda behandlas som desamma. DPAD avgör i princip bara om du driver i den riktningen eller inte. Det finns ingen dom som att "trycka lite" som en pinne.

Placerar ett textobjekt för att visa ett beslut om huruvida det trycks ned eller inte som en åtgärdskontroll.

Skapa ett skript. Filnamnet är godtyckligt, men här GamepadDpad är det .

Skriptet ser ut så här:

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

Du kan få DPAD-information Gamepad.dpad på .

DPAD har leftupdown rightegenskaper för varje riktning, och du kan bestämma om den trycks eller inte av egenskapen etc. isPressed

DpadControl.ReadValue Du kan också använda metoden för att få pressens tillstånd Vector2 i . Om inget trycks ned (0, 0), om vänster trycks ned (-1, 0) och så vidare.

När du har sparat skriptet bifogar du EventSystem det till och ställer in ett textobjekt för visning.

Prova att köra spelet och interagera med DPAD.

Vector2 Förresten, är i normaliserat tillstånd, så när du trycker diagonalt erhålls det som ett tal som (0, 7071, 0, 7071) istället för (1, 1).

Bestäm triggerpressar

Xbox-handkontroller har knappar som kallas avtryckare till vänster och höger. På PlayStation motsvarar det L2R2. Den här knappen skiljer sig från en vanlig knapp, och du kan få det belopp du trycker på i 0,0 ~ 1,0. Vissa andra styrenheter är utrustade med andra namn än triggers, men i äldre styrenheter etc. kan de helt enkelt placeras som knappar, i vilket fall bedömningen av tryckning endast hanteras som 0, 1.

Här skulle jag vilja kontrollera mängden avtryckartryckningar. Placerar ett textobjekt för visning på arbetsytan.

Skapa ett skript. Eftersom det kommer att användas någon annanstans kommer vi att namnge det här GamepadReadValue .

Skriptet ser ut så här:

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 Varje leftTriggerklass har en egenskap och rightTrigger ReadValue du kan få mängden pressar i intervallet 0,0 ~ 1,0 genom att anropa metoden. Utlösare kan också behandlas som knappar, så isPressed du kan också bedöma som. isPressed true Förresten är mängden blir ReadValue baserad på 0, 5.

När du har sparat skriptet EventSystem bifogar du det till och ställer in ett textobjekt för visning.

Prova att köra spelet och flytta avtryckaren.

Bestäm stickinformation

Pinnen kan få information om vänster spak respektive höger spak, och du kan få hur mycket pinnen trycks ner i vilken riktning. Naturligtvis, om du inte har en pinne på din kontroller, kommer du inte att kunna få den här informationen.

Stickinformation kan hämtas med , Gamepad.rightStick respektiveGamepad.leftStick.

För åtgärdsbekräftelseskriptet avleder vi skriptet som användes tidigare för att hämta utlösaren.

// 省略

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 Du kan få pressinformationen genom att ringa Vector2 metoden från ReadValue eller . Vector2 Så du kan få hur x y mycket du trycker på X-axeln och Y-axeln med och egenskaper, Om du vill få den riktning du trycker på kan du få den i fastigheten, och om du vill få det belopp du trycker på kan du magnitude normalized få det i fastigheten.

Försök att faktiskt flytta spelet och använda pinnen.

Hämta information om gamepad

Du kan få ID, namn etc. från den anslutna gamepaden. Se till exempel för att identifiera name vilken typ av styrenhet som är ansluten, eller Du kan hänvisa till vilken gamepad du deviceId ska associera med när flera gamepads är anslutna.

Här visar vi informationen i texten för att kontrollera operationen.

Skriptnamnet är godtyckligt, men här GamepadInfo är det .

Skriptet ser ut så här:

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 Du kan få olika information från den hämtade . Här är några utdrag.

När du har sparat skriptet EventSystem bifogar du det till och ställer in ett textobjekt för visning.

Prova att köra spelet för att se om informationen visas.