Utilizați hărți de acțiune pentru a atribui butoane comportamentelor de joc

Pagina actualizată :
Data creării paginii :

Mediul de verificare

Windows
  • Ferestre 11
Unity Editor
  • 2020.3.25F1
Pachet sistem de intrare
  • 1.2.0

Cerințe preliminare pentru acest sfat

Următoarele setări au fost făcute în avans ca premisă pentru descrierea acestui sfat.

Despre Action Maps

Programele de introducere a utilizatorilor pe tastaturi, șoareci și gamepad-uri au declarat practic că o anumită acțiune a fost efectuată atunci când a fost apăsat un buton. În harta de acțiuni, de exemplu, puteți defini acțiunea de "sărituri" și îi puteți atribui butoane de control și taste de tastatură. Ca urmare, programul trebuie doar să descrie procesul atunci când se efectuează o anumită acțiune. Chiar dacă atribuiți un buton pe un alt controler ca un gând ulterior, îl puteți aplica fără a schimba programul de operare.

Crearea unei hărți de acțiuni

Aici, aș dori să creez o hartă de acțiune și să afișez informațiile de intrare ale utilizatorului în text. Există mai multe modalități de a obține informații de la utilizatori utilizând Hărți de acțiune.

Faceți clic dreapta pe orice folder din proiect pentru a crea o acțiune de intrare. Locația folderului care urmează să fie creat este arbitrară, dar vă rugăm să îl gestionați în funcție de proiectul dvs. Numele fișierului este, de asemenea, arbitrar, dar aici InputActionSample este .

Când faceți dublu clic pe fișierul creat, va fi afișată următoarea fereastră.

Mai întâi, faceți clic pe butonul + din Hărți de acțiune pentru a crea o hartă de acțiune. Ca unitate de creație, dacă conținutul operației se schimbă în funcție de scenă, acesta va fi definit în acea unitate. De exemplu, în cazul unui joc de acțiune cu derulare laterală, conținutul operației se schimbă în timpul acțiunii și în meniu, astfel încât veți crea o hartă de acțiune pentru fiecare.

Aici, ca exemplu, definim o acțiune cu derulare laterală și o denumim "SideScrollActionMap".

Apoi, creați Acțiuni. Deoarece este un eșantion, nu voi face multe dintre ele, dar aici vom crea acțiuni "Move" pentru mișcare și "Attack" pentru atac. Deoarece unul a fost deja creat, vă rugăm să schimbați numele sau să creați unul nou, faceți clic pe butonul + din colțul din dreapta sus și introduceți-l.

Mai întâi, configurați configurația Mutare. Controlerul presupune că utilizați stick-ul, D-pad-ul și tastele cursorului tastaturii. În cazul unei acțiuni de derulare laterală, există cazuri în care se utilizează numai stânga și dreapta, dar aici presupunem că utilizați patru direcții având în vedere să săriți cu tasta superioară și să vă ghemuiți cu tasta în jos.

Când selectați Mutare, există o selecție de tip de acțiune la dreapta, deci setați aceasta la "Valoare".

Veți vedea tipul de control de mai jos, deci selectați Vector2. Acest lucru se datorează faptului că partea de sus și de jos sunt atribuite lui Y, iar stânga și dreapta sunt atribuite lui X.

Apoi selectați cheia pe care doriți să o atribuiți acestui eveniment. Selectați Fără legare în mijloc și selectați Cale în dreapta. Aici selectăm GamePad LeftStick.

Acest lucru leagă LeftStick-ul GamePad-ului de mișcare.

Pentru a lega și alte controlere, selectați "Adăugați legătură" din butonul + din dreapta Mutare.

Acum că No Binding este adăugat, atribuim un Dpad pentru GamePad.

În acest fel, puteți adăuga tipul de controler pe care doriți să îl acceptați, precum și tastele și stick-urile. De asemenea, este posibil să o setați special pentru o anumită consolă de jocuri.

Stick-urile și Dpads sunt butoane care presupun sus, jos, stânga și dreapta, astfel încât acestea pot fi adăugate cu aceasta, dar în cazul tastaturilor, toate sunt taste unice, deci nu există nicio definiție pentru sus, jos, stânga și dreapta. Pentru a seta tastatura în sus, în jos, la stânga sau la dreapta, selectați Adăugare sus jos Compozit dreapta stânga din butonul +.

Un vector 2D va fi apoi adăugat și îl puteți atribui fiecărui Sus Jos Stânga Dreapta, așa cum se arată în figura de mai jos.

De exemplu, dacă utilizați Sus, setați "Săgeată sus" pe tastatură. Apropo, dacă sunteți supărător să găsiți o tastă, o puteți selecta cu ușurință apăsând tasta țintă în timp ce faceți clic pe butonul "Ascultați".

Sus este acum setat la Săgeată sus.

În mod similar, setați Jos, Stânga și Dreapta și ați terminat.

Desigur, pot fi setate nu numai tastele cursorului, ci și WASD.

Apoi, configurați Attack. Atacul este ușor de atribuit, deoarece este un singur buton. Mai întâi, selectați Atac și asigurați-vă că Tipul de acțiune este un buton.

Apoi selectați Fără legare și selectați butonul pe care doriți să îl atribuiți din traseu.

Dacă doriți să adăugați mai multe, selectați "Adăugați legătură" din butonul +.

Adăugați câte aveți nevoie. Deoarece este tratată ca un buton, tastatura poate fi setată în același mod ca un controler de joc.

Când toate setările sunt finalizate, faceți clic pe "Salvați activul" pentru a salva. Puteți închide această fereastră.

În cele din urmă, cu fișierul inputactions al proiectului (în acest caz, fișierul InputActionSample pe care l-ați creat mai devreme), bifați "Generați clasa C#" în inspector. Parametrul va fi adăugat, dar faceți clic pe butonul "Aplicați" așa cum este.

Aceasta va genera un fișier script cu același nume. Acesta conține clase care sunt utile pentru utilizarea hărților de acțiune din programe.

Cum se primesc informațiile de intrare

Există mai multe moduri de a primi informații pe baza unei hărți de acțiune. Acest sfat explică trei modele, dar este mai bine să vă concentrați asupra unuia dintre ele atunci când faceți efectiv un joc. Dacă le utilizați separat, va fi dificil de gestionat.

De asemenea, dacă utilizați mai multe metode de recepție a intrărilor într-o singură scenă, procesarea poate intra în conflict intern și nu funcționează corect.

Primirea informațiilor de intrare în Trimitere mesaje

Prima metodă aici este cum să primiți informații de intrare în "Trimiteți mesaje".

De data aceasta, vreau să afișez informațiile introduse în text, așa că voi plasa un obiect text.

De asemenea, deoarece acest sfat va încerca să obțină mai multe informații de intrare, vom crea un obiect gol pentru a seta componenta separat. Numele poate fi orice.

Apoi, adăugați o componentă Introducere player la obiectul gol. Player Input este o componentă importantă pentru conectarea hărților de acțiune și a scripturilor.

În "Adăugați componentă", există "Player Input" în categoria "Input", deci adăugați-o.

Odată adăugată componenta Introducere jucător, setați harta de acțiune pe care ați creat-o în "Acțiuni". Plasați-l din proiect sau selectați-l din pictograma + din dreapta.

Verificați dacă harta implicită este cea pe care ați creat-o în harta de acțiuni.

Verificați dacă comportamentul este "Trimiteți mesaje".

Apoi, creați un script. Numele fișierului poate fi orice, dar aici InputSendMessage este .

Scenariul arată astfel:

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}";
  }
}
  • Obiectul are atașată o intrare player care setează Trimitere mesaje
  • Moștenirea de la MonoBehavior

Dacă sunt îndeplinite condițiile, atunci dacă definiți o metodă numită "OnXXXXXXXX", Metoda țintă va fi apelată atunci când se efectuează operația de acțiune specificată. "XXXXXXXX" este numele acțiunilor create în harta acțiunilor. Aici, am creat acțiuni "Move" și "Attack", astfel încât numele metodelor sunt "OnMove" și, respectiv, "OnAttack".

OnMove Puteți obține suma introdusă din argumentul InputValue . Deoarece tipul de control este setat la "Vector 2", valoarea InputValue.Get<Vector2> de intrare va fi primită în .

OnAttackInputValue.isPressed Puteți obține dacă apăsați și dvs.

După ce salvați scriptul, atașați-l la un obiect care are o componentă de intrare player. Setați și obiectul text pentru afișare.

Rulați jocul și aruncați o privire. De data aceasta, am inclus definiția gamepad-ului și a tastaturii, așa că ar trebui să funcționeze indiferent pe care o operați.

După cum puteți vedea când îl mutați, puteți vedea că metoda este apelată numai atunci când există o modificare a valorii față de starea anterioară. De exemplu, în timp ce mutați bățul spre stânga, se numește singur, dar nu spre stânga (- OnMove 1,0). OnMove Butonul Atac răspunde, de asemenea, numai în momentul în care este apăsat, iar dacă este apăsat și ținut, metoda nu este apelată.

Prin urmare, cred că utilizarea ideală nu este de a efectua procesarea jocului atunci când este apelat OnXXXXXXXX, ci de a păstra doar conținutul de intrare și de a utiliza aceste valori în procesarea actualizării jocului.

Apropo, în starea actuală, nu este apelat când butonul este eliberat, deci nu este posibil să se determine când OnAttack butonul este eliberat. Pentru a răspunde la acest lucru, selectați acțiunea Atac care definește butonul din setările hărții de acțiune și adăugați "Apăsați" din "Interacțiuni". După aceea, setați comportamentul de declanșare al presei adăugate la "Apăsați și eliberați" și salvați-l.

Când este executat, puteți vedea că este apelat chiar OnAttack și atunci când butonul este eliberat. isPressed false Deoarece devine , este, de asemenea, posibil să se determine dacă este momentul eliberării.

Apropo, vă rugăm să ștergeți această interacțiune, deoarece nu va fi utilizată în viitor.

Primiți informații cu Invocați evenimentele unității

Un al doilea mod de a primi informații este Invocați evenimentele unității, așa că haideți să încercăm acest lucru. După cum sa menționat mai sus, utilizarea mai multor metode de intrare poate provoca procesarea conflictuală, deci dacă este activată altă procesare, dezactivați-o.

Mai întâi, plasați obiectul text astfel încât informațiile de intrare să poată fi afișate.

Invocare evenimente unitate creează un obiect gol care efectuează operații conexe.

Adăugați intrare > intrare player la obiectul gol.

Setați fișierul hartă de acțiuni pe care l-ați creat pentru Acțiuni (în acest caz, InputActionSample) și setați Harta de acțiuni pe care ați creat-o (în acest caz, SideScrollActionMap) la Hartă implicită. Setați comportamentul pentru a invoca evenimente de unitate.

Creați un script. Numele este arbitrar, dar în acest caz InputInvokeUnityEvents este .

Scenariul arată astfel:

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

Numele OnMoveOnAttack metodei care este apelat atunci când utilizatorul interacționează cu acesta este , ca în cazul Trimite mesaje. În Invocați evenimentele de unitate, puteți seta numele acestei metode după cum doriți.

Când fiecare este apelat, este trecut ca InputAction.CallbackContext argument, astfel încât să puteți obține starea de intrare de acolo. Dacă setați o "valoare" în acțiune, o puteți primi în metodă, iar dacă setați ReadValue ReadValueAsButton un "buton", o puteți primi în metodă.

După salvarea scriptului, atașați intrarea playerului la obiectul pe care îl setați și setați obiectul text afișat.

Apoi, extindeți "Eveniment" și "Nume hartă acțiune (SideScrollActionMap)" în Introducerea jucătorului și ar trebui să vedeți acțiunile "Mutare" și "Atac" pe care le-ați creat.

Mai întâi, faceți clic pe butonul + de pe Mutare pentru a-l adăuga.

Obiectul din colțul din stânga jos este propriul obiect, iar funcția este setată la metoda pe care tocmai ați creat-o OnMove .

Configurați și evenimentul Atac.

Rulați jocul pentru a vedea cum funcționează.

Practic, se numește numai atunci când se schimbă aceeași valoare ca Trimiteți mesaje, dar din anumite motive metoda poate fi apelată de două ori în același timp. Nu știu cauza, dar cred că este probabil pentru că procesul de pornire și procesul continuu rulează în același timp. Cu toate acestea, cred că nu există nicio problemă dacă păstrați doar valoarea introdusă ca în cazul Trimiteți mesaje și efectuați procesarea efectivă a jocului separat în procesul de actualizare.

Utilizați un script generat automat pentru a primi informații de intrare

A treia secțiune descrie modul de obținere a informațiilor de intrare utilizând un script generat dintr-un fișier hartă de acțiune.

Deoarece există posibilitatea unor conflicte cu alte procese de achiziție, vă rugăm să dezactivați alte procese de achiziție.

Plasați un obiect text pentru a afișa informațiile de intrare.

De asemenea, creați un obiect gol pentru preluarea informațiilor de intrare. Acest articol utilizează un script generat automat, deci nu este necesar să adăugați Intrare player.

Scriptul generat automat din harta de acțiuni este doar o bibliotecă, deci creați un script de control separat. Numele este arbitrar, dar în acest caz InputScript este .

Scenariul arată astfel:

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

Definiți o clasă InputActionSample generată automat din harta de acțiuni din câmp. Această clasă definește fiecare set de acțiuni din harta de acțiuni și puteți seta evenimentele apelate atunci când sunt efectuate acele acțiuni.

Awake În metodă, InputActionSample se creează o instanță a lui și se setează evenimentul apelat în momentul acțiunii. Când OnMoveefectuați aceste operații, metoda , OnAttack se numește acum.

Cu toate acestea, deoarece setăm evenimentul doar aici, trebuie să apelăm OnEnable metoda când Enable este apelată pentru a activa harta acțiunii.

De asemenea, deoarece comportamentul de intrare al utilizatorului este tratat ca o operațiune globală, Pentru a împiedica OnDisable harta de acțiuni să facă mai mult după ce acest obiect este invalidat, apelăm metoda din Disable metodă pentru a-l dezactiva.

După salvarea scriptului, atașați-l la obiectul gol pe care l-ați creat și setați obiectul text pentru afișare.

Rulați jocul pentru a vedea cum funcționează.

După cum puteți vedea, metoda nu este apelată atunci când OnMove operația Move devine (0, 0). Nu sunt sigur de ce, dar se pare că evenimentul efectuat îl ia de fapt doar pe cel cu apăsările de taste activate.

Apropo, dacă nu ați setat Interacțiuni în harta de acțiune pentru Attack, acesta nu va fi apelat când OnAttack eliberați butonul.

Pentru a canceled gestiona acest lucru, trebuie să configurați un eveniment. Dacă nu doriți să efectuați o prelucrare specială la (0, 0), puteți apela metoda așa cum este OnMove . Același lucru este valabil și pentru 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);   // 追加
}

Rulați și verificați dacă apare Move:(0, 0) sau Attack:False.