Styring med en gamepad (Input System Package Version)

Side opdateret :
Dato for oprettelse af side :

Miljø til bekræftelse

Windows
  • Windows 11
Enhedslistens redaktør
  • 2020.3.25f1
Input System Pakke
  • 1.2.0

Forudsætninger for dette tip

Følgende indstillinger er foretaget på forhånd som en forudsætning for beskrivelsen af dette tip.

Om XInput og DirectInput

Selvom det er begrænset til Windows, er der to forbindelsesformater til spilcontrollere: DirectInput og XInput. Her svarer "Gamepad" til "XInput".

Dette Gamepad program omhandler klasser, men dette kan kun håndtere controllere, der understøtter "XInput". Hvis du vil bruge en controller, der understøtter DirectInput, skal du bruge en anden Joystick klasse.

"DirectInput" er et gammelt forbindelsesformat, og definitionen af knappen er relativt tvetydig, og den kan håndtere controllere med specielle former. Men for nylig er "XInput" blevet mainstream, og antallet af controllere, der ikke understøtter "DirectInput", stiger. "DirectInput" har knapdefinitioner som "1", "2" og "3", så spilskabere skal oprette en knapkorrespondance mellem spillet og controlleren, så de kan indstilles korrekt.

XInput defineres som den næste generation af DirectInput og inkluderer foruddefinerede A- og B-knapper, udløsere, pinde osv. Derfor kan kun en fast form af controlleren bruges, Da definitionen af knapper er veldefineret, kan spilskabere oprette spil, der passer til controlleren uden at bekymre sig om placeringen af knapper. Nylige spilcontrollere, der kun understøtter "XInput", er stigende.

Find ud af, om der trykkes på en knap

Du kan bestemme, om der trykkes på en knap eller ej efter egenskaber samt xxxxxxxx.isPressed tastatur og mus. Her vil jeg gerne vise den type knap, jeg trykker på i teksten.

Placer først et visningstekstobjekt.

Opret et script til dommen. Filnavnet er vilkårligt, men her GamepadButtons er det .

Scriptet ser sådan ud:

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 EventSystem du har gemt scriptet, skal du vedhæfte det til og konfigurere visningstekstobjektet.

Prøv at køre spillet og se, om hver knap reagerer.

Forresten defineres følgende knapper som den samme knap, selvom flere knapper er forberedt, fordi de læses forskelligt afhængigt af spilkonsollen. I hvert af ovenstående programmer er en domsproces inkluderet, så når du trykker på knappen, vises tre knapper.

Xbox,PlayStation og meget mere
bKnap cirkelknap knapØst
aButton crossButton knapSyd
xButton squareButton knapVest
yButton trekantKnap knapNord

Hvad der kan bedømmes som en knap er som følger.

  • En knap, × knap, ned-knap
  • B-knap, ○-knap, højre knap
  • X-knap, □ knap, venstre knap
  • Y-knap, pil ned-knap, op-knap
  • Knappen Start, knappen Menu
  • Vælg knap, visningsknap
  • Venstre skulderknap, L1-knap
  • Højre skulderknap, R1-knap
  • Venstre styrepind-knap
  • Højre pind-knap

Find ud af, om der trykkes på knappen

Dommen i øjeblikket af tryk kan bestemmes af egenskaberne som med xxxxxxxx.wasPressedThisFrame tastaturet og musen. Returnerer værdien af det øjeblik true , der trykkes på, og vender tilbage, selvom false den trykkes og holdes nede derefter.

Lad os vise knappen, der trykkes som tekst som en betjeningskontrol. Placer et tekstobjekt til visning.

Filnavnet på scriptet kan være hvad som helst, men her GamepadButtonsOneFrame er det .

Scriptet ser sådan ud: For nemheds skyld bedømmes kun 4 knapper.

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 EventSystem du har gemt scriptet, skal du vedhæfte det til og indstille et tekstobjekt til visning.

Prøv at køre spillet og trykke på knappen. Jeg tror, at den knap, du trykkede på, vil blive tilføjet. Du kan også se, at hvis du holder knappen nede, tilføjes der ikke nogen tekst.

Find ud af, om det øjeblik, knappen slippes

Der er ingen prøve, men du kan afgøre, om det er wasPressedThisFrame det øjeblik, du frigiver den, ved at bruge en egenskab i stedet for wasReleasedThisFrame en egenskab.

Bestem, hvornår du trykker på piletasterne

Bestemmer trykket på DPAD. Afhængigt af spilkonsollen flyver den med piletasterne og D-pad, men begge behandles som ens. DPAD bestemmer stort set kun, om du skubber i den retning eller ej. Der er ingen dom som at "skubbe lidt" som en pind.

Indsætter et tekstobjekt for at vise en beslutning, uanset om der trykkes på det eller ej, som en betjeningskontrol.

Opret et script. Filnavnet er vilkårligt, men her GamepadDpad er det .

Scriptet ser sådan ud:

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-oplysninger Gamepad.dpad på .

DPAD har leftupdown rightegenskaber for hver retning, og du kan bestemme, om den trykkes eller ej af egenskaben osv. isPressed

DpadControl.ReadValue Du kan også bruge metoden til at få pressens tilstand Vector2 i . Hvis der ikke trykkes på noget (0, 0), hvis venstre trykkes (-1, 0) osv.

Når EventSystem du har gemt scriptet, skal du vedhæfte det til og indstille et tekstobjekt til visning.

Prøv at køre spillet og interagere med DPAD.

Vector2 Forresten er i en normaliseret tilstand, så når du trykker diagonalt, opnås det som et tal som (0,7071, 0,7071) i stedet for (1, 1).

Bestem udløsertryk

Xbox-controllere har knapper kaldet udløsere til venstre og højre. På PlayStation svarer det til L2R2. Denne knap er forskellig fra en normal knap, og du kan få det beløb, du trykker på, i 0.0 ~ 1.0. Nogle andre controllere er udstyret med andre navne end udløsere, men i ældre controllere mv. Kan de simpelthen placeres som knapper, i hvilket tilfælde dommen om tryk kun håndteres som 0, 1.

Her vil jeg gerne kontrollere mængden af triggertryk. Placerer et tekstobjekt til visning på lærredet.

Opret et script. Da det vil blive brugt andre steder, vil vi navngive det her GamepadReadValue .

Scriptet ser sådan ud:

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 Hver leftTriggerklasse har en egenskab, og rightTrigger ReadValue du kan få mængden af presser i området 0,0 ~ 1,0 ved at kalde metoden. Udløsere kan også behandles som knapper, så isPressed du kan også bedømme såsom. isPressed true Forresten er mængden af bliver ReadValue baseret på 0, 5.

Når du har gemt scriptet, skal EventSystem du vedhæfte det til og indstille et tekstobjekt til visning.

Prøv at køre spillet og flytte udløseren.

Bestem pindeoplysninger

Pinden kan få informationen om henholdsvis venstre og højre pind, og du kan få mængden af, hvor meget pinden skubbes ned i hvilken retning. Hvis du ikke har en pind på din controller, kan du selvfølgelig ikke få disse oplysninger.

Stick-oplysninger kan hentes med Gamepad.rightStick henholdsvisGamepad.leftStick .

For handlingsbekræftelsesscriptet omdirigerer vi det script, der blev brugt tidligere for at få udløseren.

// 省略

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å presseinformationen ved at kalde Vector2 metoden fra ReadValue eller . Vector2 Så du kan få, hvor x y meget du trykker på X-aksen og Y-aksen med og egenskaber, Hvis du ønsker at få den retning, du trykker på, kan du få den i ejendommen, og hvis du vil have det beløb, du trykker på, kan du magnitude normalized få det i ejendommen.

Prøv faktisk at flytte spillet og betjene pinden.

Få oplysninger om gamepad

Du kan få ID, navn osv. Fra den tilsluttede gamepad. Se f.eks. til for at identificere name den type controller, der er tilsluttet, eller Du kan henvise til, hvilken gamepad du skal tilknytte, deviceId når flere gamepads er tilsluttet.

Her viser vi oplysningerne i teksten for at kontrollere handlingen.

Scriptnavnet er vilkårligt, men her GamepadInfo er det .

Scriptet ser sådan ud:

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å forskellige oplysninger fra de hentede . Her er nogle uddrag.

Når du har gemt scriptet, skal EventSystem du vedhæfte det til og indstille et tekstobjekt til visning.

Prøv at køre spillet for at se, om oplysningerne vises.