Použití map akcí k přiřazení tlačítek k chování hry

Stránky aktualizovány :
Datum vytvoření stránky :

Ověřovací prostředí

Windows
  • Systém Windows 11
Editor jednoty
  • 2020.3.25f1
Vstupní systémový balíček
  • 1.2.0

Předpoklady pro tento tip

Následující nastavení byla provedena předem jako předpoklad pro popis tohoto tipu.

O mapách akcí

Uživatelské vstupní programy na klávesnicích, myších a gamepadech v podstatě uváděly, že při stisknutí tlačítka byla provedena určitá akce. Například v mapě akcí můžete definovat akci "skákání" a přiřadit k ní tlačítka ovladače a klávesy na klávesnici. V důsledku toho musí program popsat proces pouze při provedení určité akce. I když přiřadíte tlačítko na jiném ovladači jako dodatečný nápad, můžete jej použít bez změny operačního programu.

Vytvoření mapy akcí

Zde bych chtěl vytvořit akční mapu a zobrazit vstupní informace uživatele v textu. Existuje několik způsobů, jak získat uživatelský vstup pomocí map akcí.

Klikněte pravým tlačítkem na libovolnou složku v projektu a vytvořte vstupní akci. Umístění složky, která má být vytvořena, je libovolné, ale spravujte jej podle svého projektu. Název souboru je také libovolný, ale tady InputActionSample je .

Když dvakrát kliknete na vytvořený soubor, zobrazí se následující okno.

Nejprve kliknutím na tlačítko + v Mapách akcí vytvořte mapu akcí. Pokud se obsah operace mění jako jednotka vytvoření v závislosti na scéně, bude definován v této jednotce. Například v případě akční hry s bočním posouváním se obsah operace mění během akce a v menu, takže pro každou vytvoříte akční mapu.

Zde jako příklad definujeme akci bočního posouvání a pojmenujeme ji "SideScrollActionMap".

Dále vytvořte akce. Vzhledem k tomu, že se jedná o vzorek, nebudu jich dělat mnoho, ale zde vytvoříme akce "Move" pro pohyb a "Attack" pro útok. Vzhledem k tomu, že jeden již byl vytvořen, změňte název nebo vytvořte nový, klikněte na tlačítko + v pravém horním rohu a zadejte jej.

Nejprve nakonfigurujte konfiguraci přesunu. Ovladač předpokládá, že používáte páčku, směrový ovladač a kurzorové klávesy klávesnice. V případě akce s bočním posouváním existují případy, kdy se používá pouze levý a pravý krok, ale zde předpokládáme, že používáte čtyři směry s ohledem na skok s horní klávesou a přikrčení s klávesou dolů.

Když vyberete Přesunout, vpravo je výběr Typ akce, takže jej nastavte na "Hodnota".

Níže uvidíte typ ovládacího prvku, takže vyberte Vector2. Je to proto, že horní a dolní část jsou přiřazeny k Y a levá a pravá strana jsou přiřazeny k X.

Pak vyberte klíč, který chcete této události přiřadit. Uprostřed vyberte Bez vazby a vpravo vyberte Cesta. Zde vybereme GamePad LeftStick.

To váže levou páčku GamePadu k pohybu.

Chcete-li svázat i jiné ovladače, vyberte možnost "Přidat vazbu" z tlačítka + napravo od tlačítka Přesunout.

Nyní, když je přidána možnost Bez vazby, přiřadíme GamePadu Dpad.

Tímto způsobem můžete přidat typ ovladače, který chcete podporovat, stejně jako klíče a klíče. Je také možné jej nastavit speciálně pro konkrétní herní konzoli.

Sticks a Dpads jsou tlačítka, která předpokládají nahoru, dolů, doleva a doprava, takže je lze přidat, ale v případě klávesnic jsou to všechny jednotlivé klávesy, takže neexistuje definice pro nahoru, dolů, doleva a doprava. Pokud chcete klávesnici nastavit nahoru, dolů, doleva nebo doprava, vyberte na tlačítku + možnost Add Up Down Left Right Composite (Přidat nahoru dolů, dolů, doleva, doprava, složená).

Poté bude přidán 2D vektor a můžete jej přiřadit každému Nahoru dolů, Doleva, Vpravo, jak je znázorněno na obrázku níže.

Pokud například používáte Nahoru, nastavte na klávesnici "Šipka nahoru". Mimochodem, pokud máte potíže s nalezením klíče, můžete jej snadno vybrat stisknutím cílové klávesy a kliknutím na tlačítko "Poslouchat".

Šipka nahoru je nyní nastavena na šipku nahoru.

Podobně nastavte Dolů, Vlevo a Vpravo a máte hotovo.

Samozřejmě lze nastavit nejen kurzorové klávesy, ale také WASD.

Dále nakonfigurujte útok. Útok je snadné přiřadit, protože se jedná o jediné tlačítko. Nejprve vyberte Útok a ujistěte se, že Typ akce je tlačítko.

Pak vyberte možnost Bez vazby a vyberte tlačítko, které chcete přiřadit z cesty.

Pokud chcete přidat další, vyberte "Přidat vazbu" z tlačítka +.

Přidejte jich tolik, kolik potřebujete. Vzhledem k tomu, že se s klávesnicí zachází jako s tlačítkem, lze ji nastavit stejným způsobem jako herní ovladač.

Po dokončení všech nastavení klikněte na "Uložit datový zdroj" pro uložení. Toto okno můžete zavřít.

Nakonec se souborem inputactions projektu (v tomto případě se souborem InputActionSample, který jste vytvořili dříve), zaškrtněte "Generovat třídu jazyka C#" v inspektoru. Parametr bude přidán, ale klikněte na tlačítko "Použít" tak, jak je.

Tím se vygeneruje soubor skriptu se stejným názvem. Obsahuje třídy, které jsou užitečné pro použití map akcí z programů.

Jak přijímat vstupní informace

Existuje několik způsobů, jak přijímat vstupy na základě mapy akcí. Tento tip vysvětluje tři vzory, ale je lepší se zaměřit na jeden z nich, když skutečně děláte hru. Pokud je používáte samostatně, bude obtížné je spravovat.

Pokud v jedné scéně použijete více vstupních metod příjmu, může dojít k internímu konfliktu zpracování a nemusí fungovat správně.

Příjem vstupních informací v části Odesílání zpráv

První metodou je, jak přijímat vstupní informace v "Odeslat zprávy".

Tentokrát chci zobrazit zadané informace v textu, takže umístím textový objekt.

Protože se tento tip pokusí získat více vstupních informací, vytvoříme prázdný objekt pro samostatné nastavení komponenty. Název může být cokoliv.

Dále přidejte komponentu Player Input do prázdného objektu. Vstup hráče je důležitou součástí pro propojení akčních map a skriptů.

V "Přidat komponentu" je v kategorii "Vstup" "Vstup hráče", takže jej přidejte.

Po přidání komponenty Player Input (Vstup hráče) nastavte mapu akcí, kterou jste vytvořili v části "Actions". Přetáhněte ji z projektu nebo ji vyberte pomocí ikony + vpravo.

Ověřte, zda výchozí mapa je ta, kterou jste vytvořili v mapě akcí.

Ověřte, zda je chování "Odesílat zprávy".

Dále vytvořte skript. Název souboru může být cokoliv, ale tady InputSendMessage je .

Skript vypadá takto:

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}";
  }
}
  • Objekt má připojený vstup hráče, který nastavuje odesílání zpráv
  • Dědění z MonoBehaviour

Pokud jsou podmínky splněny, pak pokud definujete metodu nazvanou "OnXXXXXXXX", Cílová metoda bude volána při provedení zadané operace akce. "XXXXXXXX" je název akcí vytvořených v mapě akcí. Zde jsme vytvořili akce "Move" a "Attack", takže názvy metod jsou "OnMove" a "OnAttack".

OnMove Zadanou částku můžete získat z argumentu InputValue . Protože Typ řízení je nastaven na "Vektor 2", vstupní hodnota InputValue.Get<Vector2> bude přijata v .

OnAttackInputValue.isPressed Můžete také zjistit, zda tlačíte.

Po uložení skriptu jej připojte k objektu, který má komponentu Player Input. Nastavte také textový objekt pro zobrazení.

Spusťte hru a podívejte se. Tentokrát jsem zahrnul definici gamepadu a klávesnice, takže by to mělo fungovat bez ohledu na to, který z nich používáte.

Jak můžete vidět, když ji přesunete, můžete vidět, že metoda je volána pouze v případě, že dojde ke změně hodnoty z předchozího stavu. Například při pohybu hůlky doleva se nazývá jednostranně, ale ne doleva (- OnMove 1,0). OnMove Tlačítko Attack také reaguje pouze v okamžiku, kdy je stisknuto, a pokud je stisknuto a podrženo, metoda není volána.

Proto si myslím, že ideální použití není provádět zpracování hry, když je voláno OnXXXXXXXX, ale zachovat pouze vstupní obsah a použít tyto hodnoty při zpracování aktualizace hry.

Mimochodem, v aktuálním stavu není voláno, když je tlačítko uvolněno, takže není možné určit, kdy OnAttack je tlačítko uvolněno. Chcete-li na to reagovat, vyberte akci Útok, která definuje tlačítko v nastavení mapy akcí, a přidejte "Stisknout" z "Interakce". Poté nastavte chování spouštěče přidaného tisku na "Stiskněte a uvolněte" a uložte jej.

Při spuštění můžete vidět, že je volán, i OnAttack když je tlačítko uvolněno. isPressed false Vzhledem k tomu, že se stává , je také možné určit, zda se jedná o načasování uvolnění.

Mimochodem, prosím odstraňte tuto interakci, protože nebude v budoucnu použita.

Příjem vstupu pomocí událostí vyvolání jednoty

Druhým způsobem, jak přijímat vstupy, je vyvolání událostí jednoty, takže to zkusíme. Jak bylo uvedeno výše, použití více metod zadávání může způsobit konfliktní zpracování, takže pokud je povoleno jiné zpracování, zakažte jej.

Nejprve umístěte textový objekt tak, aby bylo možné zobrazit vstupní informace.

Možnost Vyvolat události jednoty vytvoří prázdný objekt, který provádí související operace.

Přidat vstup > vstup přehrávače do prázdného objektu.

Nastavte soubor mapy akcí, který jste vytvořili pro akce (v tomto případě InputActionSample), a nastavte mapu akcí, kterou jste vytvořili (v tomto případě SideScrollActionMap), na výchozí mapu. Nastavte chování pro vyvolání událostí Unity.

Vytvořte skript. Název je libovolný, ale v tomto případě InputInvokeUnityEvents je .

Skript vypadá takto:

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

Název metodyOnMoveOnAttack, který je volán při interakci uživatele s ní je , jako v případě Odeslat zprávy. V části Invoke Unity Events můžete nastavit název této metody, jak chcete.

Když je každý volán, je předán jako InputAction.CallbackContext argument, takže odtud můžete získat stav vstupu. Pokud nastavíte "hodnotu" v akci, můžete ji obdržet v metodě a pokud ReadValue nastavíte ReadValueAsButton "tlačítko", můžete ji obdržet v metodě.

Po uložení skriptu připojte vstup přehrávače k objektu, který nastavujete, a nastavte objekt zobrazovaného textu.

Dále rozbalte "Událost" a "Název akční mapy (SideScrollActionMap)" ve vstupu hráče a měli byste vidět akce "Přesun" a "Útok", které jste vytvořili.

Nejprve klikněte na tlačítko + na Přesunout a přidejte jej.

Objekt v levém dolním rohu je váš vlastní objekt a funkce je nastavena na metodu, kterou jste právě vytvořili OnMove .

Nakonfigurujte také událost útoku.

Spusťte hru a podívejte se, jak funguje.

V podstatě je volána pouze tehdy, když se změní stejná hodnota jako Odeslat zprávy, ale z nějakého důvodu může být metoda volána dvakrát současně. Neznám příčinu, ale myslím, že je to pravděpodobně proto, že proces spuštění a kontinuální proces běží současně. Myslím si však, že není problém, pokud si ponecháte pouze zadanou hodnotu jako v případě Odeslat zprávy a samotné zpracování hry provedete samostatně v procesu aktualizace.

Použití automaticky generovaného skriptu k příjmu vstupních informací

Třetí část popisuje, jak získat vstupní informace pomocí skriptu generovaného ze souboru mapy akcí.

Vzhledem k tomu, že existuje možnost konfliktu s jinými akvizičními procesy, zakažte prosím jiné akviziční procesy.

Umístěte textový objekt, aby se zobrazily vstupní informace.

Vytvořte také prázdný objekt pro načítání vstupních informací. Tento článek používá automaticky generovaný skript, takže nemusíte přidávat vstup hráče.

Skript automaticky generovaný z mapy akcí je pouze knihovna, takže vytvořte samostatný řídicí skript. Název je libovolný, ale v tomto případě InputScript je .

Skript vypadá takto:

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

Definujte automaticky generovanou třídu InputActionSample z mapy akcí v poli. Tato třída definuje každou sadu akcí v mapě akcí a můžete nastavit události, které jsou volány při provádění těchto akcí.

Awake V metodě InputActionSample je vytvořena instance a je nastavena událost volaná v době akce. Při OnMoveprovádění těchto operací je nyní volána metoda , OnAttack .

Protože zde však nastavujeme pouze událost, musíme volat metodu, když Enable je volána, OnEnable abychom povolili mapu akcí.

Vzhledem k tomu, že chování vstupu uživatele je považováno za globální operaci, Chcete-li zabránit OnDisable tomu, aby mapa akcí po zneplatnění tohoto objektu provedla další akce, zavoláme metodu v Disable metodě, která jej zakáže.

Po uložení skriptu jej připojte k prázdnému objektu, který jste vytvořili, a nastavte textový objekt pro zobrazení.

Spusťte hru a podívejte se, jak funguje.

Jak vidíte, metoda není volána, když OnMove se operace Move stane (0, 0). Nejsem si jistý proč, ale zdá se, že provedená událost ve skutečnosti trvá pouze ta s povolenými úhozy.

Mimochodem, pokud jste nenastavili Interakce na mapě akcí pro Attack, nebude volána při OnAttack uvolnění tlačítka.

Chcete-li canceled to zvládnout, musíte nastavit událost. Pokud nechcete provádět speciální zpracování v (0, 0), můžete volat metodu tak, jak je OnMove . Totéž platí pro 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);   // 追加
}

Spusťte a ověřte, zda se zobrazí Move:(0, 0) nebo Attack:False.