Utiliser des cartes d’action pour attribuer des boutons aux comportements de jeu

Page mise à jour :
Date de création de la page :

Environnement de vérification

Windows
  • Fenêtres 11
Éditeur Unity
  • 2020.3.25f1
Package système d’entrée
  • 1.2.0

Conditions préalables à cette astuce

Les paramètres suivants ont été définis à l’avance comme prémisse pour la description de cette astuce.

À propos des cartes d’action

Les programmes d’entrée utilisateur sur les claviers, les souris et les manettes de jeu indiquaient essentiellement qu’une certaine action était effectuée lorsqu’un bouton était pressé. Dans la carte d’action, par exemple, vous pouvez définir l’action de « sauter » et lui attribuer des boutons de contrôleur et des touches de clavier. Par conséquent, le programme n’a besoin de décrire le processus que lorsqu’une action spécifique est effectuée. Même si vous attribuez un bouton sur un autre contrôleur après coup, vous pouvez l’appliquer sans modifier le programme d’exploitation.

Création d’une carte d’action

Ici, je voudrais créer une carte d’action et afficher les informations d’entrée de l’utilisateur dans le texte. Il existe plusieurs façons d’obtenir des entrées utilisateur à l’aide de cartes d’action.

Cliquez avec le bouton droit sur un dossier du projet pour créer une action d’entrée. L’emplacement du dossier à créer est arbitraire, mais veuillez le gérer en fonction de votre projet. Le nom du fichier est également arbitraire, mais le voici InputActionSample .

Lorsque vous double-cliquez sur le fichier créé, la fenêtre suivante s’affiche.

Tout d’abord, cliquez sur le bouton + dans Cartes d’action pour créer une carte d’action. En tant qu’unité de création, si le contenu de l’opération change en fonction de la scène, il sera défini dans cette unité. Par exemple, dans le cas d’un jeu d’action à défilement latéral, le contenu de l’opération change pendant l’action et dans le menu, vous allez donc créer une carte d’action pour chacun.

Ici, à titre d’exemple, nous définissons une action de défilement latéral et la nommons « SideScrollActionMap ».

Ensuite, créez des actions. Comme il s’agit d’un échantillon, je n’en ferai pas beaucoup, mais ici nous allons créer des actions « Move » pour le mouvement et « Attack » pour l’attaque. Comme il en a déjà été créé, veuillez changer le nom ou en créer un nouveau, cliquez sur le bouton + dans le coin supérieur droit et entrez-le.

Tout d’abord, configurez la configuration Move. Le contrôleur suppose que vous utilisez les touches du clavier, du pavé directionnel et du clavier. Dans le cas d’une action de défilement latéral, il existe des cas où seules la gauche et la droite sont utilisées, mais nous supposons ici que vous utilisez quatre directions en envisageant de sauter avec la touche supérieure et de vous accroupir avec la touche bas.

Lorsque vous sélectionnez Déplacer, il y a une sélection Type d’action à droite, alors définissez-la sur « Valeur ».

Vous verrez le type de contrôle ci-dessous, alors sélectionnez Vector2. En effet, le haut et le bas sont affectés à Y, et la gauche et la droite sont affectées à X.

Sélectionnez ensuite la clé que vous souhaitez attribuer à cet événement. Sélectionnez Aucune liaison au milieu et sélectionnez Chemin à droite. Ici, nous sélectionnons le GamePad LeftStick.

Cela lie le LeftStick du GamePad au Move.

Pour lier également d’autres contrôleurs, sélectionnez « Ajouter une liaison » à partir du bouton + à droite de Déplacer.

Maintenant que le No Binding est ajouté, nous attribuons un Dpad pour le GamePad.

De cette façon, vous pouvez ajouter le type de contrôleur que vous souhaitez prendre en charge, ainsi que les touches et les bâtons. Il est également possible de le définir spécifiquement pour une console de jeu spécifique.

Les sticks et les Dpads sont des boutons qui supposent haut, bas, gauche et droite, de sorte qu’ils peuvent être ajoutés avec cela, mais dans le cas des claviers, ce sont tous des touches simples, il n’y a donc pas de définition pour haut, bas, gauche et droite. Pour configurer le clavier vers le haut, le bas, la gauche ou la droite, sélectionnez Ajouter en bas Composite gauche droite à partir de la touche +.

Un vecteur 2D sera ensuite ajouté et vous pourrez l’attribuer à chaque Ascendant Bas Gauche Droit, comme indiqué dans la figure ci-dessous.

Par exemple, si vous utilisez Up, définissez « Flèche haut » sur votre clavier. Soit dit en passant, si vous avez du mal à trouver une touche, vous pouvez facilement la sélectionner en appuyant sur la touche cible tout en cliquant sur le bouton « Écouter ».

Up est maintenant défini sur Flèche haute.

De même, réglez Down, Left et Right et vous avez terminé.

Bien sûr, non seulement les touches de curseur, mais aussi WASD peuvent être définies.

Ensuite, configurez Attack. L’attaque est facile à attribuer car il s’agit d’un seul bouton. Tout d’abord, sélectionnez Attaque et assurez-vous que le type d’action est un bouton.

Sélectionnez ensuite Aucune liaison et sélectionnez le bouton que vous souhaitez affecter dans le chemin d’accès.

Si vous souhaitez en ajouter d’autres, sélectionnez « Ajouter une liaison » à partir du bouton +.

Ajoutez-en autant que nécessaire. Comme il est traité comme un bouton, le clavier peut être réglé de la même manière qu’un contrôleur de jeu.

Lorsque tous les paramètres sont terminés, cliquez sur « Enregistrer la ressource » pour enregistrer. Vous pouvez fermer cette fenêtre.

Enfin, avec le fichier inputactions du projet (dans ce cas, le fichier InputActionSample que vous avez créé précédemment), cochez la case « Generate C# Class » dans l’inspecteur. Le paramètre sera ajouté, mais cliquez sur le bouton « Appliquer » tel quel.

Cela générera un fichier de script portant le même nom. Il contient des classes utiles pour utiliser des cartes d’action à partir de programmes.

Comment recevoir des informations d’entrée

Il existe plusieurs façons de recevoir des entrées basées sur une carte d’action. Cette astuce explique trois modèles, mais il est préférable de se concentrer sur l’un d’entre eux lors de la création d’un jeu. Si vous les utilisez séparément, ce sera difficile à gérer.

En outre, si vous utilisez plusieurs méthodes de réception d’entrée dans une seule scène, le traitement peut entrer en conflit interne et ne pas fonctionner correctement.

Recevoir des informations d’entrée dans Envoyer des messages

La première méthode ici est comment recevoir des informations d’entrée dans « Envoyer des messages ».

Cette fois, je veux afficher les informations saisies dans le texte, donc je vais placer un objet texte.

De plus, étant donné que cette astuce tentera d’obtenir plusieurs informations d’entrée, nous allons créer un objet vide pour définir le composant séparément. Le nom peut être n’importe quoi.

Ensuite, ajoutez un composant Player Input à l’objet vide. L’entrée du joueur est un composant important pour connecter les cartes d’action et les scripts.

Dans « Ajouter un composant », il y a « Entrée du joueur » dans la catégorie « Entrée », alors ajoutez-le.

Une fois le composant Entrée du joueur ajouté, définissez la carte d’action que vous avez créée dans « Actions ». Déposez-le du projet ou sélectionnez-le dans l’icône + à droite.

Vérifiez que la carte par défaut est celle que vous avez créée dans la carte d’action.

Vérifiez que le comportement est « Envoyer des messages ».

Ensuite, créez un script. Le nom de fichier peut être n’importe quoi, mais le voici InputSendMessage .

Le script ressemble à ceci :

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}";
  }
}
  • L’objet est accompagné d’une entrée de lecteur qui définit Envoyer des messages
  • Hériter de MonoBehaviour

Si les conditions sont remplies, alors si vous définissez une méthode appelée « OnXXXXXXXX », La méthode cible sera appelée lorsque l’opération d’action spécifiée est effectuée. « XXXXXXXX » est le nom des actions créées dans la carte d’action. Ici, nous avons créé des actions « Move » et « Attack », de sorte que les noms de méthode sont « OnMove » et « OnAttack », respectivement.

OnMove Vous pouvez obtenir le montant saisi à partir de l’argument InputValue de . Étant donné que le type de contrôle est défini sur « Vecteur 2 », la valeur InputValue.Get<Vector2> d’entrée sera reçue dans .

OnAttackInputValue.isPressed Vous pouvez également savoir si vous appuyez également.

Après avoir enregistré le script, attachez-le à un objet doté d’un composant Player Input. Définissez également l’objet texte pour l’affichage.

Lancez le jeu et jetez un coup d’œil. Cette fois, j’ai inclus la définition de la manette de jeu et du clavier, donc cela devrait fonctionner peu importe celui que vous utilisez.

Comme vous pouvez le voir lorsque vous la déplacez, vous pouvez voir que la méthode est appelée uniquement lorsqu’il y a un changement de valeur par rapport à l’état précédent. Par exemple, en déplaçant le bâton vers la gauche, il est appelé de manière unique, mais pas vers la gauche (- OnMove 1,0). OnMove Le bouton Attack ne répond également qu’au moment où il est enfoncé, et s’il est enfoncé et maintenu, la méthode n’est pas appelée.

Par conséquent, je pense que l’utilisation idéale n’est pas d’effectuer le traitement du jeu lorsque OnXXXXXXXX est appelé, mais de ne conserver que le contenu d’entrée et d’utiliser ces valeurs dans le traitement de mise à jour du jeu.

Soit dit en passant, dans l’état actuel, il n’est pas appelé lorsque le bouton est relâché, il n’est donc pas possible de déterminer quand OnAttack le bouton est relâché. Pour répondre à cela, sélectionnez l’action Attaque qui définit le bouton dans les paramètres de la carte d’action et ajoutez « Appuyer » à partir de « Interactions ». Après cela, définissez le comportement de déclenchement de la presse ajoutée sur « Press And Release » et enregistrez-le.

Lorsqu’il est exécuté, vous pouvez voir que est appelé même OnAttack lorsque le bouton est relâché. isPressed false Puisqu’il devient , il est également possible de déterminer s’il s’agit du moment de la libération.

Au fait, veuillez supprimer cette interaction car elle ne sera pas utilisée à l’avenir.

Recevoir des entrées avec Invoke Unity Events

Une deuxième façon de recevoir des entrées est d’appeler des événements Unity, alors essayons ceci. Comme mentionné ci-dessus, l’utilisation de plusieurs méthodes d’entrée peut provoquer un traitement conflictuel, donc si un autre traitement est activé, désactivez-le.

Tout d’abord, placez l’objet texte de manière à ce que les informations d’entrée puissent être affichées.

Invoke Unity Events crée un objet vide qui effectue des opérations associées.

Ajoutez Input > Player Input à l’objet vide.

Définissez le fichier de mappage d’action que vous avez créé pour Actions (dans ce cas, InputActionSample) et définissez la carte d’action que vous avez créée (dans ce cas, SideScrollActionMap) sur Carte par défaut. Définissez le comportement pour appeler des événements Unity.

Créez un script. Le nom est arbitraire, mais dans ce cas InputInvokeUnityEvents , il est .

Le script ressemble à ceci :

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

Le nom OnMoveOnAttack de la méthode appelée lorsque l’utilisateur interagit avec elle est , comme dans le cas de Send Messages. Dans Appeler des événements Unity, vous pouvez définir le nom de cette méthode comme vous le souhaitez.

Lorsque chacun est appelé, il est passé en tant qu’argument InputAction.CallbackContext , de sorte que vous pouvez obtenir l’état d’entrée à partir de là. Si vous définissez une « valeur » dans l’action, vous pouvez la recevoir dans la méthode, et si vous définissez un « bouton », vous ReadValue pouvez la recevoir dans la ReadValueAsButton méthode.

Après avoir enregistré le script, joignez l’entrée du lecteur à l’objet que vous définissez et définissez l’objet texte d’affichage.

Ensuite, développez « Événement » et « Nom de la carte d’action (SideScrollActionMap) » dans Entrée du joueur et vous devriez voir les actions « Déplacer » et « Attaquer » que vous avez créées.

Tout d’abord, cliquez sur le bouton + sur Déplacer pour l’ajouter.

L’objet dans le coin inférieur gauche est votre propre objet et la fonction est définie sur la méthode que vous venez de créer OnMove .

Configurez également l’événement Attack.

Exécutez le jeu pour voir comment il fonctionne.

Fondamentalement, il est appelé uniquement lorsque la même valeur que Envoyer des messages change, mais pour une raison quelconque, la méthode peut être appelée deux fois en même temps. Je ne connais pas la cause, mais je pense que c’est probablement parce que le processus de démarrage et le processus continu fonctionnent en même temps. Cependant, je pense qu’il n’y a pas de problème si vous ne conservez que la valeur saisie comme dans le cas de Envoyer des messages et effectuez le traitement du jeu séparément dans le processus de mise à jour.

Utiliser un script généré automatiquement pour recevoir des informations d’entrée

La troisième section décrit comment obtenir des informations d’entrée à l’aide d’un script généré à partir d’un fichier de mappage d’actions.

Comme il existe une possibilité de conflits avec d’autres processus d’acquisition, veuillez désactiver les autres processus d’acquisition.

Placez un objet texte pour afficher les informations d’entrée.

Créez également un objet vide pour récupérer les informations d’entrée. Cet article utilise un script généré automatiquement, vous n’avez donc pas besoin d’ajouter une entrée de lecteur.

Le script généré automatiquement à partir de la carte d’action n’est qu’une bibliothèque, créez donc un script de contrôle distinct. Le nom est arbitraire, mais dans ce cas InputScript , il est .

Le script ressemble à ceci :

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

Définissez une classe InputActionSample générée automatiquement à partir de la carte d’action dans le champ. Cette classe définit chaque jeu d’actions dans la carte d’actions et vous pouvez définir les événements qui sont appelés lorsque ces actions sont effectuées.

Awake Dans la méthode, InputActionSample une instance de est créée et l’événement appelé au moment de l’action est défini. Lorsque OnMovevous effectuez ces opérations, la méthode , OnAttack est désormais appelée.

Cependant, comme nous ne définissons l’événement qu’ici, nous OnEnable devons appeler la méthode when Enable pour activer la carte d’action.

En outre, étant donné que le comportement d’entrée de l’utilisateur est traité comme une opération globale, Pour empêcher OnDisable la carte d’action de faire plus après l’invalidation de cet objet, nous appelons la méthode dans Disable la méthode pour le désactiver.

Après avoir enregistré le script, attachez-le à l’objet vide que vous avez créé et définissez l’objet texte pour l’affichage.

Exécutez le jeu pour voir comment il fonctionne.

Comme vous pouvez le voir, la méthode n’est pas appelée lorsque OnMove l’opération Move devient (0, 0). Je ne sais pas pourquoi, mais il semble que l’événement exécuté ne prenne en fait que celui avec les frappes activées.

Soit dit en passant, si vous n’avez pas défini Interactions dans la carte d’action pour Attaque, il ne sera pas appelé lorsque OnAttack vous relâcherez le bouton.

Pour canceled gérer cela, vous devez configurer un événement. Si vous ne souhaitez pas effectuer de traitement spécial à (0, 0), vous pouvez appeler la méthode telle quelle OnMove . Il en va de même pour 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);   // 追加
}

Exécutez et vérifiez que Move:(0, 0) ou Attack:False s’affiche.