Veiksmų žemėlapių naudojimas norint priskirti mygtukus žaidimo elgsenai

Puslapis atnaujintas :
Puslapio sukūrimo data :

Tikrinimo aplinka

Windows
  • Langai 11
"Unity" redaktorius
  • 2020.3.25f1
Įvesties sistemos paketas
  • 1.2.0

Būtinos šio patarimo sąlygos

Šie nustatymai buvo atlikti iš anksto kaip šio patarimo aprašymo prielaida.

Apie veiksmų žemėlapius

Vartotojo įvesties programos klaviatūrose, pelėse ir žaidimų pultuose iš esmės teigė, kad tam tikras veiksmas buvo atliktas paspaudus mygtuką. Pavyzdžiui, veiksmų žemėlapyje galite apibrėžti "šokinėjimo" veiksmą ir priskirti valdiklio mygtukus bei klaviatūros klavišus. Todėl programai reikia tik aprašyti procesą, kai atliekamas konkretus veiksmas. Net jei priskiriate mygtuką kitam valdikliui kaip pasekmę, galite jį pritaikyti nekeisdami operacinės programos.

Veiksmų žemėlapio kūrimas

Čia norėčiau sukurti veiksmų žemėlapį ir tekste parodyti vartotojo įvesties informaciją. Yra keli būdai, kaip gauti vartotojo įvestį naudojant veiksmų žemėlapius.

Dešiniuoju pelės mygtuku spustelėkite bet kurį projekto aplanką, kad sukurtumėte įvesties veiksmą. Kuriamo aplanko vieta yra savavališka, tačiau valdykite ją pagal savo projektą. Failo pavadinimas taip pat yra savavališkas, bet čia InputActionSample jis yra .

Dukart spustelėjus sukurtą failą, bus rodomas šis langas.

Pirmiausia spustelėkite mygtuką + veiksmų žemėlapiuose, kad sukurtumėte veiksmų žemėlapį. Kaip kūrimo vienetas, jei operacijos turinys keičiasi priklausomai nuo scenos, jis bus apibrėžtas tame vienete. Pavyzdžiui, šoninio slinkimo veiksmo žaidimo atveju operacijos turinys keičiasi veiksmo metu ir meniu, todėl kiekvienam sukursite veiksmų žemėlapį.

Čia, kaip pavyzdį, apibrėžiame šoninio slinkimo veiksmą ir pavadiname jį "SideScrollActionMap".

Tada sukurkite veiksmus. Kadangi tai yra pavyzdys, aš jų nedarysiu daug, bet čia mes sukursime "Move" veiksmus judėjimui ir "Attack" atakai. Kadangi vienas jau buvo sukurtas, pakeiskite pavadinimą arba sukurkite naują, spustelėkite + mygtuką viršutiniame dešiniajame kampe ir įveskite jį.

Pirmiausia sukonfigūruokite Perkelti konfigūraciją. Valdiklis daro prielaidą, kad naudojate lazdelės, D-pad ir klaviatūros žymeklio klavišus. Šoninio slinkimo veiksmo atveju yra atvejų, kai naudojamos tik kairės ir dešinės pusės, tačiau čia darome prielaidą, kad naudojate keturias kryptis, atsižvelgdami į šokinėjimą viršutiniu klavišu ir susilenkimą žemyn klavišu.

Kai pasirenkate Perkelti, dešinėje yra pasirinktas veiksmo tipas, todėl nustatykite jį į "Reikšmė".

Žemiau pamatysite valdymo tipą, todėl pasirinkite Vector2. Taip yra todėl, kad viršus ir apačia priskiriami Y, o kairė ir dešinė – X.

Tada pasirinkite raktą, kurį norite priskirti šiam įvykiui. Viduryje pasirinkite Be įrišimo ir dešinėje pasirinkite Kelias. Čia mes pasirenkame GamePad LeftStick.

Tai susieja "GamePad" kairįjį "Stick" su judėjimu.

Norėdami susieti ir kitus valdiklius, pasirinkite "Pridėti įrišimą" iš mygtuko +, esančio dešinėje nuo Perkelti.

Dabar, kai pridėtas "No Binding", "GamePad" priskiriame "Dpad".

Tokiu būdu galite pridėti valdiklio, kurį norite palaikyti, tipą, taip pat raktus ir lazdeles. Taip pat galima jį nustatyti specialiai konkrečiai žaidimų konsolei.

"Sticks" ir "Dpads" yra mygtukai, kurie prisiima aukštyn, žemyn, kairėn ir dešinėn, todėl juos galima pridėti prie to, tačiau klaviatūrų atveju jie visi yra atskiri klavišai, todėl nėra aukštyn, žemyn, kairėn ir dešinėn apibrėžimo. Norėdami nustatyti klaviatūrą aukštyn, žemyn, kairėn arba dešinėn, mygtuko + skiltyje pasirinkite Pridėti aukštyn žemyn kairįjį dešinįjį kompozitą.

Tada bus pridėtas 2D vektorius ir galėsite jį priskirti kiekvienam aukštyn žemyn kairėn dešinėn, kaip parodyta paveikslėlyje žemiau.

Pavyzdžiui, jei naudojate "Up", klaviatūroje nustatykite "Rodyklė aukštyn". Beje, jei jums sunku rasti raktą, galite lengvai jį pasirinkti paspausdami tikslinį klavišą, spustelėdami mygtuką "Klausyti".

Dabar nustatyta rodyklė aukštyn.

Panašiai nustatykite žemyn, kairėn ir dešinėn ir viskas.

Žinoma, galima nustatyti ne tik žymeklio klavišus, bet ir WASD.

Tada sukonfigūruokite "Attack". "Attack" lengva priskirti, nes tai yra vienas mygtukas. Pirmiausia pasirinkite Ataka ir įsitikinkite, kad veiksmo tipas yra mygtukas.

Tada pasirinkite Nėra susiejimo ir pasirinkite mygtuką, kurį norite priskirti iš kelio.

Jei norite pridėti daugiau, mygtuko + skiltyje pasirinkite "Pridėti įrišimą".

Pridėkite tiek, kiek jums reikia. Kadangi jis traktuojamas kaip mygtukas, klaviatūrą galima nustatyti taip pat, kaip ir žaidimo valdiklį.

Kai visi nustatymai bus baigti, spustelėkite "Išsaugoti turtą", kad išsaugotumėte. Šį langą galite uždaryti.

Galiausiai, naudodami projekto įvesties veiksmų failą (šiuo atveju anksčiau sukurtą failą InputActionSample), inspektoriuje pažymėkite "Generuoti C# klasę". Parametras bus pridėtas, tačiau spustelėkite mygtuką "Taikyti", kaip jis yra.

Tai sugeneruos scenarijaus failą tuo pačiu pavadinimu. Jame yra klasių, kurios yra naudingos naudojant veiksmų žemėlapius iš programų.

Kaip gauti įvesties informaciją

Yra keletas būdų, kaip gauti įvestį pagal veiksmų žemėlapį. Šis patarimas paaiškina tris modelius, tačiau geriau sutelkti dėmesį į vieną iš jų, kai iš tikrųjų kuriate žaidimą. Jei juos naudosite atskirai, tai bus sunku valdyti.

Be to, jei vienoje scenoje naudojate kelis įvesties gavimo metodus, apdorojimas gali prieštarauti viduje ir neveikti tinkamai.

Įvesties informacijos gavimas programoje Siųsti pranešimus

Pirmasis metodas yra tai, kaip gauti įvesties informaciją "Siųsti pranešimus".

Šį kartą noriu parodyti įvestą informaciją tekste, todėl įdėsiu teksto objektą.

Be to, kadangi šis patarimas bandys gauti kelias įvesties informaciją, sukursime tuščią objektą, kad komponentas būtų nustatytas atskirai. Pavadinimas gali būti bet koks.

Tada pridėkite leistuvo įvesties komponentą prie tuščio objekto. Žaidėjo įvestis yra svarbus komponentas jungiant veiksmų žemėlapius ir scenarijus.

Skiltyje "Pridėti komponentą" kategorijoje "Įvestis" yra "Žaidėjo įvestis", todėl pridėkite ją.

Pridėję leistuvo įvesties komponentą, nustatykite veiksmų žemėlapį, kurį sukūrėte "Veiksmai". Numeskite jį iš projekto arba pasirinkite iš + piktogramos dešinėje.

Patikrinkite, ar numatytasis žemėlapis yra tas, kurį sukūrėte veiksmų žemėlapyje.

Patikrinkite, ar veikimas yra "Siųsti pranešimus".

Tada sukurkite scenarijų. Failo pavadinimas gali būti bet koks, bet čia InputSendMessage jis yra .

Scenarijus atrodo taip:

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}";
  }
}
  • Prie objekto pridėta leistuvo įvestis, kuri nustato Siųsti pranešimus
  • Paveldėjimas iš MonoBehaviour

Jei sąlygos įvykdytos, tada, jei apibrėžiate metodą, vadinamą "OnXXXXXXXX", Tikslinis metodas bus vadinamas, kai bus atlikta nurodyta veiksmo operacija. "XXXXXXXX" yra veiksmų žemėlapyje sukurtų veiksmų pavadinimas. Čia mes sukūrėme veiksmus "Perkelti" ir "Ataka", todėl metodų pavadinimai yra atitinkamai "OnMove" ir "OnAttack".

OnMove Įvestą sumą galite gauti iš argumento InputValue . Kadangi valdymo tipas nustatytas į "Vector 2", įvesties vertė InputValue.Get<Vector2> bus gauta .

OnAttackInputValue.isPressed Galite sužinoti, ar taip pat spaudžiate.

Įrašę scenarijų, pridėkite jį prie objekto, kuriame yra leistuvo įvesties komponentas. Taip pat nustatykite, kad teksto objektas būtų rodomas.

Paleiskite žaidimą ir pažiūrėkite. Šį kartą įtraukiau žaidimų pulto ir klaviatūros apibrėžimą, todėl jis turėtų veikti, nesvarbu, kurį iš jų naudojate.

Kaip matote, kai jį perkeliate, matote, kad metodas vadinamas tik tada, kai pasikeičia vertė nuo ankstesnės būsenos. Pavyzdžiui, perkeliant lazdą į kairę, ji vadinama vienpusiškai, bet ne į kairę (- OnMove 1,0). OnMove "Attack" mygtukas taip pat reaguoja tik tuo metu, kai jis paspaudžiamas, o jei jis paspaudžiamas ir laikomas, metodas nėra vadinamas.

Todėl manau, kad idealus naudojimas yra ne atlikti žaidimo apdorojimą, kai vadinamas OnXXXXXXXX, bet išlaikyti tik įvesties turinį ir naudoti šias reikšmes žaidimo atnaujinimo apdorojime.

Beje, dabartinėje būsenoje jis nėra iškviečiamas, kai mygtukas atleidžiamas, todėl neįmanoma nustatyti, kada OnAttack mygtukas atleidžiamas. Norėdami į tai atsakyti, veiksmų žemėlapio nustatymuose pasirinkite veiksmą "Ataka", kuris apibrėžia mygtuką, ir pridėkite "Paspauskite" iš "Sąveikos". Po to nustatykite pridėtos spaudos paleidimo elgseną į "Paspauskite ir atleiskite" ir išsaugokite.

Kai įvykdoma, galite matyti, kad tai vadinama net OnAttack tada, kai mygtukas atleidžiamas. isPressed false Kadangi tai tampa , taip pat galima nustatyti, ar tai yra išleidimo laikas.

Beje, ištrinkite šią sąveiką, nes ji nebus naudojama ateityje.

Gaukite informaciją naudodami "Invoke Unity Events"

Antras būdas gauti indėlį yra iškviesti vienybės renginius, todėl pabandykime tai. Kaip minėta pirmiau, naudojant kelis įvesties metodus gali atsirasti nesuderinamas apdorojimas, todėl, jei įjungtas kitas apdorojimas, išjunkite jį.

Pirmiausia įdėkite teksto objektą taip, kad būtų galima rodyti įvesties informaciją.

Iškviesti vienybės įvykius sukuria tuščią objektą, kuris atlieka susijusias operacijas.

Įtraukite įvestį > leistuvo įvestį į tuščią objektą.

Nustatykite veiksmų schemos failą, kurį sukūrėte veiksmams (šiuo atveju InputActionSample), ir nustatykite sukurtą veiksmų schemą (šiuo atveju SideScrollActionMap) į Numatytasis žemėlapis. Nustatykite elgesį, kad iškviestumėte vienybės įvykius.

Sukurkite scenarijų. Pavadinimas yra savavališkas, tačiau šiuo atveju InputInvokeUnityEvents jis yra .

Scenarijus atrodo taip:

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

Metodo pavadinimasOnMoveOnAttack, kuris vadinamas, kai vartotojas su juo sąveikauja, yra , kaip ir pranešimų siuntimo atveju. Iškvieskite vienybės įvykius galite nustatyti šio metodo pavadinimą, kaip norite.

Kai kiekvienas iškviečiamas, jis perduodamas kaip argumentas InputAction.CallbackContext , todėl iš ten galite gauti įvesties būseną. Jei veiksme nustatysite "vertę", galite ją gauti metode, o jei nustatysite ReadValue ReadValueAsButton "mygtuką", galite jį gauti metode.

Įrašę scenarijų, pridėkite leistuvo įvestį prie objekto, kurį nustatote, ir nustatykite rodomo teksto objektą.

Tada žaidėjo įvestyje išplėskite "Įvykis" ir "Veiksmų žemėlapio pavadinimas (SideScrollActionMap)" ir turėtumėte pamatyti savo sukurtus veiksmus "Perkelti" ir "Ataka".

Pirmiausia spustelėkite + mygtuką Perkelti, kad jį pridėtumėte.

Apatiniame kairiajame kampe esantis objektas yra jūsų objektas, o funkcija nustatyta pagal ką tik sukurtą OnMove metodą .

Taip pat sukonfigūruokite "Attack" įvykį.

Paleiskite žaidimą, kad pamatytumėte, kaip jis veikia.

Iš esmės jis vadinamas tik tada, kai pasikeičia ta pati vertė kaip siųsti pranešimus, tačiau dėl kokių nors priežasčių metodas gali būti vadinamas du kartus tuo pačiu metu. Nežinau priežasties, bet manau, kad tikriausiai taip yra todėl, kad pradžios procesas ir nuolatinis procesas vyksta tuo pačiu metu. Tačiau manau, kad nėra jokių problemų, jei išsaugosite tik įvestą reikšmę, kaip ir "Send Messages" atveju, ir atliksite faktinį žaidimo apdorojimą atskirai atnaujinimo procese.

Automatiškai sugeneruoto scenarijaus naudojimas įvesties informacijai gauti

Trečiame skyriuje aprašoma, kaip gauti įvesties informaciją naudojant scenarijų, sugeneruotą iš veiksmų schemos failo.

Kadangi yra konfliktų su kitais įsigijimo procesais galimybė, išjunkite kitus įsigijimo procesus.

Padėkite teksto objektą, kad būtų rodoma įvesties informacija.

Taip pat sukurkite tuščią objektą įvesties informacijai gauti. Šiame straipsnyje naudojamas automatiškai sugeneruotas scenarijus, todėl jums nereikia pridėti leistuvo įvesties.

Scenarijus, automatiškai sugeneruotas iš veiksmų schemos, yra tik biblioteka, todėl sukurkite atskirą valdiklio scenarijų. Pavadinimas yra savavališkas, tačiau šiuo atveju InputScript jis yra .

Scenarijus atrodo taip:

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

Apibrėžkite automatiškai sugeneruotą klasę InputActionSample iš lauko veiksmų schemos. Ši klasė apibrėžia kiekvieną veiksmų rinkinį veiksmų schemoje, o jūs galite nustatyti įvykius, kurie iškviečiami, kai tie veiksmai atliekami.

Awake Metode sukuriamas egzempliorius ir nustatomas įvykis, InputActionSample vadinamas veiksmo metu. Kai OnMoveatliekate šias operacijas, dabar vadinamas , OnAttack metodas.

Tačiau kadangi įvykį nustatome tik čia, turime OnEnable iškviesti metodą, kai Enable jis iškviečiamas, kad įjungtume veiksmų žemėlapį.

Be to, kadangi vartotojo įvesties elgsena traktuojama kaip visuotinė operacija, Norėdami, kad OnDisable veiksmų žemėlapis nebūtų papildomas po to, kai šis objektas bus pripažintas negaliojančiu, mes vadiname metodą Disable , kaip jį išjungti.

Išsaugoję scenarijų, pridėkite jį prie tuščio sukurto objekto ir nustatykite teksto objektą rodyti.

Paleiskite žaidimą, kad pamatytumėte, kaip jis veikia.

Kaip matote, metodas nėra vadinamas, kai OnMove perkėlimo operacija tampa (0, 0). Nežinau, kodėl, bet atrodo, kad atliktas įvykis iš tikrųjų užima tik tą, kuriame įjungti klavišų paspaudimai.

Beje, jei "Attack" veiksmų žemėlapyje nenustatėte sąveikų, jis nebus iškviestas, kai OnAttack atleisite mygtuką.

Norėdami canceled tai padaryti, turite nustatyti įvykį. Jei nenorite atlikti specialaus apdorojimo (0, 0), galite skambinti metodu taip, kaip jis yra OnMove . Tas pats pasakytina ir apie "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);   // 追加
}

Paleiskite ir patikrinkite, ar pasirodo Move:(0, 0) arba Attack:False.