Verwenden von Aktionskarten zum Zuweisen von Schaltflächen zu Spielverhalten

Diese Seite wurde aktualisiert :
Erstellungsdatum der Seite :

Verifizierungsumgebung

Fenster
  • Windows 11
Unity-Editor
  • 2020.3.25f1
Eingabesystem-Paket
  • 1.2.0

Voraussetzungen für diesen Tipp

Die folgenden Einstellungen wurden im Vorfeld als Prämisse für die Beschreibung dieses Tipps vorgenommen.

Informationen zu Action Maps

Benutzereingabeprogramme auf Tastaturen, Mäusen und Gamepads gaben im Grunde an, dass eine bestimmte Aktion ausgeführt wurde, wenn eine Taste gedrückt wurde. In der Action Map können Sie z.B. die Aktion "Springen" definieren und ihr Controller-Tasten und Tastaturtasten zuweisen. Dadurch muss das Programm den Prozess nur beschreiben, wenn eine bestimmte Aktion ausgeführt wird. Auch wenn Sie nachträglich eine Taste auf einer anderen Steuerung zuweisen, können Sie diese anwenden, ohne das Bedienprogramm zu ändern.

Erstellen einer Aktionskarte

Hier möchte ich eine Aktionskarte erstellen und die Eingabeinformationen des Benutzers im Text anzeigen. Es gibt mehrere Möglichkeiten, Benutzereingaben mithilfe von Aktionskarten zu erhalten.

Klicken Sie mit der rechten Maustaste auf einen beliebigen Ordner im Projekt, um eine Eingabeaktion zu erstellen. Der Speicherort des zu erstellenden Ordners ist willkürlich, aber bitte verwalten Sie ihn entsprechend Ihrem Projekt. Der Dateiname ist auch willkürlich, aber hier InputActionSample ist er .

Wenn Sie auf die erstellte Datei doppelklicken, wird das folgende Fenster angezeigt.

Klicken Sie zunächst auf die Schaltfläche + in Action Maps, um eine Action Map zu erstellen. Wenn sich der Inhalt des Vorgangs je nach Szene ändert, wird er als Erstellungseinheit in dieser Einheit definiert. Bei einem Side-Scrolling-Actionspiel ändert sich beispielsweise der Inhalt des Vorgangs während der Aktion und im Menü, sodass Sie für jeden eine Aktionskarte erstellen.

Hier definieren wir als Beispiel eine Side-Scrolling-Aktion und nennen sie "SideScrollActionMap".

Erstellen Sie als Nächstes Aktionen. Da es sich um ein Beispiel handelt, werde ich nicht viele davon machen, aber hier werden wir "Move"-Aktionen für die Bewegung und "Attack" für den Angriff erstellen. Da bereits ein Name erstellt wurde, ändern Sie bitte den Namen oder erstellen Sie einen neuen, klicken Sie auf die Schaltfläche + in der oberen rechten Ecke und geben Sie ihn ein.

Konfigurieren Sie zunächst die Move-Konfiguration. Der Controller geht davon aus, dass Sie die Stick-, Steuerkreuz- und Tastaturcursortasten verwenden. Im Falle einer Side-Scrolling-Aktion gibt es Fälle, in denen nur links und rechts verwendet werden, aber hier gehen wir davon aus, dass Sie vier Richtungen verwenden, wenn Sie mit der oberen Taste springen und mit der Abwärtstaste in die Hocke gehen.

Wenn Sie "Verschieben" auswählen, befindet sich auf der rechten Seite eine Auswahl des Aktionstyps, also setzen Sie diese auf "Wert".

Unten sehen Sie den Steuerelementtyp, wählen Sie also Vector2 aus. Dies liegt daran, dass die Ober- und Unterseite Y und die linke und rechte Seite X zugewiesen sind.

Wählen Sie dann die Taste aus, die Sie diesem Ereignis zuweisen möchten. Wählen Sie in der Mitte Keine Bindung und rechts Pfad aus. Hier wählen wir das GamePad LeftStick aus.

Dadurch wird der linke Stick des GamePads an den Move gebunden.

Um auch andere Controller zu binden, wählen Sie "Bindung hinzufügen" aus der Schaltfläche + rechts neben Verschieben.

Nachdem nun No Binding hinzugefügt wurde, weisen wir dem GamePad ein Dpad zu.

Auf diese Weise können Sie den Controller-Typ, den Sie unterstützen möchten, sowie die Tasten und Sticks hinzufügen. Es ist auch möglich, es speziell für eine bestimmte Spielkonsole einzustellen.

Sticks und Dpads sind Tasten, die oben, unten, links und rechts annehmen, so dass sie damit hinzugefügt werden können, aber im Fall von Tastaturen sind sie alle einzelne Tasten, sodass es keine Definition für oben, unten, links und rechts gibt. Um die Tastatur nach oben, unten, links oder rechts einzustellen, wählen Sie auf der Schaltfläche + die Option Add Up Down Left Right Composite aus.

Anschließend wird ein 2D-Vektor hinzugefügt, den Sie jedem Oben, Unten, Links, Rechts zuweisen können, wie in der folgenden Abbildung gezeigt.

Wenn Sie z. B. die Aufwärtspfeiltaste verwenden, stellen Sie auf Ihrer Tastatur "Pfeil nach oben" ein. Übrigens, wenn Sie Schwierigkeiten haben, eine Taste zu finden, können Sie sie einfach auswählen, indem Sie die Zieltaste drücken, während Sie auf die Schaltfläche "Anhören" klicken.

Nach oben ist jetzt auf Pfeil nach oben eingestellt.

Legen Sie in ähnlicher Weise Down, Left und Right fest, und Sie sind fertig.

Natürlich können nicht nur Cursortasten, sondern auch WASD gesetzt werden.

Konfigurieren Sie als Nächstes Angriff. Der Angriff ist einfach zuzuweisen, da es sich um eine einzige Taste handelt. Wählen Sie zunächst Angriff und stellen Sie sicher, dass der Aktionstyp eine Schaltfläche ist.

Wählen Sie dann Keine Bindung aus, und wählen Sie die Schaltfläche aus, die Sie aus dem Pfad zuweisen möchten.

Wenn Sie weitere hinzufügen möchten, wählen Sie über die Schaltfläche + die Option "Bindung hinzufügen".

Fügen Sie so viele hinzu, wie Sie benötigen. Da sie wie eine Taste behandelt wird, kann die Tastatur wie ein Gamecontroller eingestellt werden.

Wenn alle Einstellungen abgeschlossen sind, klicken Sie zum Speichern auf "Asset speichern". Sie können dieses Fenster schließen.

Aktivieren Sie abschließend mit der inputactions-Datei des Projekts (in diesem Fall der InputActionSample-Datei, die Sie zuvor erstellt haben) im Inspektor die Option "C#-Klasse generieren". Der Parameter wird hinzugefügt, aber klicken Sie unverändert auf die Schaltfläche "Übernehmen".

Dadurch wird eine Skriptdatei mit demselben Namen generiert. Es enthält Klassen, die für die Verwendung von Aktionskarten aus Programmen nützlich sind.

So erhalten Sie Eingabeinformationen

Es gibt mehrere Möglichkeiten, Eingaben basierend auf einer Aktionskarte zu erhalten. Dieser Tipp erklärt drei Muster, aber es ist besser, sich auf eines davon zu konzentrieren, wenn man tatsächlich ein Spiel entwickelt. Wenn Sie sie separat verwenden, wird es mühsam sein, sie zu verwalten.

Wenn Sie mehrere Eingabeempfangsmethoden in einer einzelnen Szene verwenden, kann die Verarbeitung intern in Konflikt geraten und nicht ordnungsgemäß funktionieren.

Empfangen von Eingabeinformationen in Nachrichten senden

Die erste Methode hier ist, wie Sie Eingabeinformationen in "Nachrichten senden" erhalten.

Dieses Mal möchte ich die eingegebenen Informationen im Text anzeigen, also werde ich ein Textobjekt platzieren.

Da dieser Tipp versucht, mehrere Eingabeinformationen zu erhalten, erstellen wir ein leeres Objekt, um die Komponente separat festzulegen. Der Name kann alles sein.

Fügen Sie als Nächstes dem leeren Objekt eine Player Input-Komponente hinzu. Die Spielereingabe ist eine wichtige Komponente für die Verbindung von Actionmaps und Skripten.

Unter "Komponente hinzufügen" gibt es "Spielereingabe" in der Kategorie "Eingabe", also fügen Sie sie hinzu.

Nachdem die Komponente "Player-Eingabe" hinzugefügt wurde, legen Sie die Aktionskarte fest, die Sie unter "Aktionen" erstellt haben. Legen Sie es aus dem Projekt ab oder wählen Sie es über das +-Symbol auf der rechten Seite aus.

Stellen Sie sicher, dass die Standardzuordnung diejenige ist, die Sie in der Aktionszuordnung erstellt haben.

Vergewissern Sie sich, dass das Verhalten "Nachrichten senden" lautet.

Erstellen Sie als Nächstes ein Skript. Der Dateiname kann alles sein, aber hier InputSendMessage ist er .

Das Skript sieht wie folgt aus:

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class InputSendMessage : MonoBehaviour
{
  /// <summary>情報を表示させるテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  /// <summary>
  /// Move アクションが実行されたときに呼ばれる。
  /// </summary>
  /// <param name="inputValue">入力量。</param>
  public void OnMove(InputValue inputValue)
  {
    var vec = inputValue.Get<Vector2>();
    TextObject.text = $"Move:({vec.x:f2}, {vec.y:f2})\n{TextObject.text}";
  }

  /// <summary>
  /// Attack アクションが実行されたときに呼ばれる。
  /// </summary>
  public void OnAttack(InputValue inputValue)
  {
    TextObject.text = $"Attack:{inputValue.isPressed}\n{TextObject.text}";
  }
}
  • Dem Objekt ist eine Playereingabe angefügt, die Send Messages festlegt
  • Erben von MonoBehaviour

Wenn die Bedingungen erfüllt sind, definieren Sie eine Methode namens "OnXXXXXXXX", Die Zielmethode wird aufgerufen, wenn der angegebene Aktionsvorgang ausgeführt wird. "XXXXXXXX" ist der Name der Aktionen, die in der Aktionszuordnung erstellt wurden. Hier haben wir "Move"- und "Attack"-Aktionen erstellt, sodass die Methodennamen "OnMove" bzw. "OnAttack" lauten.

OnMove Sie können den eingegebenen Betrag aus dem Argument InputValue von abrufen. Da der Kontrolltyp auf "Vektor 2" eingestellt ist, wird der Eingabewert InputValue.Get<Vector2> in empfangen.

OnAttackInputValue.isPressed Sie können auch herausfinden, ob Sie hineindrücken.

Nachdem Sie das Skript gespeichert haben, fügen Sie es an ein Objekt an, das über eine Player-Eingabekomponente verfügt. Legen Sie auch das Textobjekt für die Anzeige fest.

Starten Sie das Spiel und werfen Sie einen Blick darauf. Dieses Mal habe ich die Definition des Gamepads und der Tastatur beigefügt, so dass es funktionieren sollte, egal welches Sie bedienen.

Wie Sie beim Verschieben sehen können, können Sie sehen, dass die Methode nur aufgerufen wird, wenn sich der Wert gegenüber dem vorherigen Zustand ändert. Wenn Sie z. B. den Stick nach links bewegen, wird er zielstrebig aufgerufen, aber nicht nach links (- OnMove 1,0). OnMove Die Attack-Taste reagiert auch nur in dem Moment, in dem sie gedrückt wird, und wenn sie gedrückt gehalten wird, wird die Methode nicht aufgerufen.

Daher denke ich, dass die ideale Verwendung nicht darin besteht, die Spielverarbeitung durchzuführen, wenn OnXXXXXXXX aufgerufen wird, sondern nur den Eingabeinhalt beizubehalten und diese Werte in der Update-Verarbeitung des Spiels zu verwenden.

Im aktuellen Zustand wird es übrigens nicht aufgerufen, wenn die Taste losgelassen wird, so dass nicht festgestellt werden kann, wann OnAttack die Taste losgelassen wird. Um darauf zu reagieren, wählen Sie in den Einstellungen der Aktionskarte die Aktion Angriff aus, die die Schaltfläche definiert, und fügen Sie unter "Interaktionen" "Drücken" hinzu. Setzen Sie danach das Triggerverhalten des hinzugefügten Drückens auf "Drücken und Loslassen" und speichern Sie es.

Bei der Ausführung können Sie sehen, dass dies auch OnAttack dann aufgerufen wird, wenn die Taste losgelassen wird. isPressed false Da es wird, ist es auch möglich zu bestimmen, ob es sich um den Zeitpunkt der Veröffentlichung handelt.

Bitte löschen Sie diese Interaktion übrigens, da sie in Zukunft nicht mehr verwendet wird.

Empfangen von Eingaben mit Aufrufen von Unity-Ereignissen

Eine zweite Möglichkeit, Eingaben zu empfangen, ist Invoke Unity Events, also probieren wir das aus. Wie oben erwähnt, kann die Verwendung mehrerer Eingabemethoden zu Verarbeitungskonflikten führen. Wenn also eine andere Verarbeitung aktiviert ist, deaktivieren Sie sie.

Platzieren Sie zunächst das Textobjekt so, dass die Eingabeinformationen angezeigt werden können.

Unity-Ereignisse aufrufen erstellt ein leeres Objekt, das verwandte Vorgänge ausführt.

Fügen Sie Eingabe > Player-Eingabe zum leeren Objekt hinzu.

Legen Sie die Aktionszuordnungsdatei fest, die Sie für Aktionen erstellt haben (in diesem Fall InputActionSample), und legen Sie die von Ihnen erstellte Aktionszuordnung (in diesem Fall SideScrollActionMap) auf Standardzuordnung fest. Legen Sie das Verhalten so fest, dass Unity-Ereignisse aufgerufen werden.

Erstellen Sie ein Skript. Der Name ist willkürlich, aber in diesem Fall InputInvokeUnityEvents ist es .

Das Skript sieht wie folgt aus:

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class InputInvokeUnityEvents : MonoBehaviour
{
  /// <summary>情報を表示させるテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  /// <summary>
  /// Move 操作を行ったときに呼ばれる。
  /// </summary>
  /// <param name="context">コールバック内容。</param>
  public void OnMove(InputAction.CallbackContext context)
  {
    var vec = context.ReadValue<Vector2>();
    TextObject.text = $"Move:({vec.x:f2}, {vec.y:f2})\n{TextObject.text}";
  }

  /// <summary>
  /// Move 操作を行ったときに呼ばれる。
  /// </summary>
  /// <param name="context">コールバック内容。</param>
  public void OnAttack(InputAction.CallbackContext context)
  {
    var value = context.ReadValueAsButton();
    TextObject.text = $"Attack:{value}\n{TextObject.text}";
  }
}

Der MethodennameOnMoveOnAttack, der aufgerufen wird, wenn der Benutzer mit ihr interagiert, ist , wie im Fall von Nachrichten senden. Unter Unity-Ereignisse aufrufen können Sie diesen Methodennamen nach Belieben festlegen.

Wenn each aufgerufen wird, wird es als InputAction.CallbackContext Argument übergeben, sodass Sie den Eingabestatus von dort abrufen können. Wenn Sie einen "Wert" in der Aktion festlegen, können Sie ihn in der Methode empfangen, und wenn Sie eine "Schaltfläche" festlegenReadValueAsButton, können Sie ReadValue ihn in der Methode empfangen.

Hängen Sie nach dem Speichern des Skripts die Player-Eingabe an das Objekt an, das Sie festlegen, und legen Sie das Anzeigetextobjekt fest.

Erweitern Sie als Nächstes "Event" und "Action Map Name (SideScrollActionMap)" in der Spielereingabe und Sie sollten die von Ihnen erstellten Aktionen "Move" und "Attack" sehen.

Klicken Sie zunächst auf die Schaltfläche + bei Verschieben, um sie hinzuzufügen.

Das Objekt in der unteren linken Ecke ist Ihr eigenes Objekt, und die Funktion ist auf die Methode festgelegt, die Sie gerade erstellt haben OnMove .

Konfigurieren Sie auch das Ereignis Angriff.

Führen Sie das Spiel aus, um zu sehen, wie es funktioniert.

Grundsätzlich wird sie nur aufgerufen, wenn sich derselbe Wert wie Send Messages ändert, aber aus irgendeinem Grund kann die Methode zweimal gleichzeitig aufgerufen werden. Ich kenne die Ursache nicht, aber ich denke, es liegt wahrscheinlich daran, dass der Startprozess und der kontinuierliche Prozess gleichzeitig laufen. Ich denke jedoch, dass es kein Problem ist, wenn man wie bei Send Messages nur den eingegebenen Wert beibehält und die eigentliche Spielverarbeitung separat im Update-Prozess durchführt.

Verwenden eines automatisch generierten Skripts, um Eingabeinformationen zu erhalten

Im dritten Abschnitt wird beschrieben, wie Sie Eingabeinformationen mithilfe eines Skripts abrufen, das aus einer Action-Map-Datei generiert wurde.

Da die Möglichkeit von Konflikten mit anderen Akquisitionsprozessen besteht, deaktivieren Sie bitte andere Akquisitionsprozesse.

Platzieren Sie ein Textobjekt, um die Eingabeinformationen anzuzeigen.

Erstellen Sie außerdem ein leeres Objekt zum Abrufen von Eingabeinformationen. In diesem Artikel wird ein automatisch generiertes Skript verwendet, sodass Sie keine Spielereingabe hinzufügen müssen.

Das Skript, das automatisch aus der Aktionskarte generiert wird, ist nur eine Bibliothek, also erstellen Sie ein separates Steuerskript. Der Name ist willkürlich, aber in diesem Fall InputScript ist es .

Das Skript sieht wie folgt aus:

using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class InputScript : MonoBehaviour
{
  /// <summary>情報を表示させるテキストオブジェクト。</summary>
  [SerializeField] private Text TextObject;

  /// <summary>アクションマップから自動生成されたクラス。</summary>
  private InputActionSample _actionMap;

  private void Awake()
  {
    // 各操作を行ったときに呼ばれるイベントを設定する
    _actionMap = new InputActionSample();
    _actionMap.SideScrollActionMap.Move.performed += context => OnMove(context);
    _actionMap.SideScrollActionMap.Attack.performed += context => OnAttack(context);
  }

  private void OnEnable()
  {
    // このオブジェクトが有効になったときにアクションマップを有効にする
    _actionMap.Enable();
  }

  private void OnDisable()
  {
    // このオブジェクトが無効になったときにアクションマップが余計な動作を起こさないように無効にする
    _actionMap.Disable();
  }

  /// <summary>
  /// Move 操作をした時に呼ばれるメソッドです。
  /// </summary>
  /// <param name="context">コールバックパラメータ。</param>
  public void OnMove(InputAction.CallbackContext context)
  {
    // Move の入力量を取得
    var vec = context.ReadValue<Vector2>();
    TextObject.text = $"Move:({vec.x:f2}, {vec.y:f2})\n{TextObject.text}";
  }

  /// <summary>
  /// Attack 操作をした時に呼ばれるメソッドです。
  /// </summary>
  /// <param name="context">コールバックパラメータ。</param>
  public void OnAttack(InputAction.CallbackContext context)
  {
    // Attack ボタンの状態を取得
    var value = context.ReadValueAsButton();
    TextObject.text = $"Attack:{value}\n{TextObject.text}";
  }
}

Definieren Sie eine automatisch generierte Klasse InputActionSample aus der Aktionszuordnung im Feld. Diese Klasse definiert jeden Aktionssatz in der Aktionszuordnung, und Sie können die Ereignisse festlegen, die aufgerufen werden, wenn diese Aktionen ausgeführt werden.

Awake In der Methode wird eine Instanz von erstellt, und das Ereignis, das zum Zeitpunkt der Aktion aufgerufen wird, InputActionSample wird festgelegt. Wenn OnMoveSie diese Vorgänge ausführen, wird jetzt die Methode aufgerufen OnAttack .

Da wir hier jedoch nur das Ereignis festlegen, müssen wir OnEnable die Methode aufrufen, wenn Enable sie aufgerufen wird, um die Aktionszuordnung zu aktivieren.

Da das Eingabeverhalten des Benutzers als globaler Vorgang behandelt wird, Um zu verhindern, dass OnDisable die Aktionszuordnung zusätzliche Aktionen ausführt, nachdem dieses Objekt ungültig gemacht wurde, rufen wir die Methode in Disable der Methode auf, um sie zu deaktivieren.

Nachdem Sie das Skript gespeichert haben, hängen Sie es an das leere Objekt an, das Sie erstellt haben, und legen Sie das Textobjekt für die Anzeige fest.

Führen Sie das Spiel aus, um zu sehen, wie es funktioniert.

Wie Sie sehen können, wird die Methode nicht aufgerufen, wenn OnMove der Move-Vorgang zu (0, 0) wird. Ich bin mir nicht sicher, warum, aber es scheint, dass das ausgeführte Ereignis nur das mit aktivierten Tastenanschlägen verwendet.

Übrigens, wenn Sie in der Aktionskarte für Angriff keine Interaktionen festgelegt haben, wird diese nicht aufgerufen, wenn OnAttack Sie die Taste loslassen.

Um dies zu canceled handhaben, müssen Sie ein Ereignis einrichten. Wenn Sie bei (0, 0) keine spezielle Verarbeitung durchführen möchten, können Sie die Methode so aufrufen, wie sie ist OnMove . Das Gleiche gilt für Attack.

private void Awake()
{
  // 各操作を行ったときに呼ばれるイベントを設定する
  _actionMap = new InputActionSample();
  _actionMap.SideScrollActionMap.Move.performed += context => OnMove(context);
  _actionMap.SideScrollActionMap.Attack.performed += context => OnAttack(context);
  _actionMap.SideScrollActionMap.Move.canceled += context => OnMove(context);       // 追加
  _actionMap.SideScrollActionMap.Attack.canceled += context => OnAttack(context);   // 追加
}

Führen Sie die Ausführung aus, und stellen Sie sicher, dass Move:(0, 0) oder Attack:False angezeigt wird.