Gunakan peta tindakan untuk memperuntukkan butang kepada tingkah laku permainan

Laman dikemaskini :
Tarikh penciptaan halaman :

Persekitaran pengesahan

Windows
  • Windows 11
Penyunting Perpaduan
  • 2020.3.25f1
Pakej Sistem Input
  • 1.2.0

Prasyarat untuk petua ini

Tetapan berikut telah dibuat terlebih dahulu sebagai premis untuk penerangan petua ini.

Perihal Peta Tindakan

Program input pengguna pada papan kekunci, tikus, dan pad permainan pada dasarnya menyatakan bahawa tindakan tertentu dilakukan apabila butang ditekan. Dalam peta tindakan, sebagai contoh, anda boleh menentukan tindakan "melompat" dan menetapkan butang pengawal dan kekunci papan kekunci kepadanya. Akibatnya, program ini hanya perlu menerangkan proses apabila tindakan tertentu dilakukan. Walaupun anda menetapkan butang pada pengawal lain sebagai pemikiran semula, anda boleh menggunakannya tanpa mengubah program operasi.

Mencipta Peta Tindakan

Di sini, saya ingin membuat peta tindakan dan memaparkan maklumat input pengguna dalam teks. Terdapat beberapa cara untuk mendapatkan input pengguna menggunakan Peta Tindakan.

Klik kanan sebarang folder dalam projek untuk mencipta Tindakan Input. Lokasi folder yang akan dibuat adalah sewenang-wenangnya, tetapi sila uruskannya mengikut projek anda. Nama fail juga sewenang-wenangnya, tetapi di sini InputActionSample ia adalah .

Apabila anda dwiklik fail yang dibuat, tetingkap berikut akan dipaparkan.

Mula-mula, klik butang + dalam Peta Tindakan untuk mencipta peta tindakan. Sebagai unit penciptaan, jika kandungan operasi berubah bergantung pada tempat kejadian, ia akan ditakrifkan dalam unit tersebut. Sebagai contoh, dalam kes permainan tindakan tatal sisi, kandungan operasi berubah semasa tindakan dan dalam menu, jadi anda akan membuat peta tindakan untuk setiap satu.

Di sini, sebagai contoh, kami mentakrifkan tindakan tatal sisi dan menamakannya "SideScrollActionMap".

Seterusnya, buat Tindakan. Oleh kerana ia adalah sampel, saya tidak akan membuat banyak daripada mereka, tetapi di sini kita akan membuat tindakan "Bergerak" untuk pergerakan dan "Serangan" untuk serangan. Oleh kerana satu telah dibuat, sila tukar nama atau buat yang baru, klik butang + di sudut kanan atas dan masukkannya.

Mula-mula, konfigurasikan konfigurasi Alih. Pengawal menganggap bahawa anda menggunakan tongkat, pad D dan kekunci kursor papan kekunci. Dalam kes tindakan tatal sisi, terdapat kes di mana hanya kiri dan kanan digunakan, tetapi di sini kami menganggap bahawa anda menggunakan empat arah yang mempertimbangkan untuk melompat dengan kekunci atas dan membongkok dengan kekunci bawah.

Apabila anda memilih Alih, terdapat pilihan Jenis Tindakan di sebelah kanan, jadi tetapkannya kepada "Nilai".

Anda akan melihat Jenis Kawalan di bawah, jadi pilih Vector2. Ini kerana bahagian atas dan bawah diberikan kepada Y, dan kiri dan kanan diberikan kepada X.

Kemudian pilih kekunci yang ingin anda tugaskan ke acara ini. Pilih Tiada Mengikat di tengah dan pilih Laluan di sebelah kanan. Di sini kita pilih GamePad LeftStick.

Ini mengikat LeftStick GamePad untuk bergerak.

Untuk mengikat pengawal lain juga, pilih "Tambah Mengikat" dari butang + di sebelah kanan Alih.

Sekarang bahawa No Binding ditambah, kami menetapkan Dpad untuk GamePad.

Dengan cara ini, anda boleh menambah jenis pengawal yang ingin anda sokong, serta kekunci dan tongkat. Ia juga mungkin untuk menetapkannya khusus untuk konsol permainan tertentu.

Tongkat dan Dpad adalah butang yang menganggap atas, bawah, kiri, dan kanan, jadi ia boleh ditambah dengan ini, tetapi dalam kes papan kekunci, semuanya adalah kunci tunggal, jadi tidak ada definisi untuk atas, bawah, kiri, dan kanan. Untuk menyediakan papan kekunci ke atas, bawah, kiri atau kanan, pilih Tambah Komposit Kanan Kiri Ke Bawah daripada butang +.

Vektor 2D kemudiannya akan ditambah dan anda boleh menugaskannya kepada setiap Up Down Left Right, seperti yang ditunjukkan dalam gambar di bawah.

Sebagai contoh, jika anda menggunakan Up, tetapkan "Anak Panah" pada papan kekunci anda. Dengan cara ini, jika anda menyusahkan untuk mencari kunci, anda boleh memilihnya dengan mudah dengan menekan kekunci sasaran sambil mengklik butang "Dengar".

Up kini disediakan kepada Up Arrow.

Begitu juga, tetapkan Bawah, Kiri dan Kanan dan anda sudah selesai.

Sudah tentu, bukan sahaja kekunci kursor tetapi juga WASD boleh ditetapkan.

Seterusnya, konfigurasikan Serangan. Serangan mudah diberikan kerana ia adalah satu butang. Mula-mula, pilih Serangan dan pastikan Jenis Tindakan ialah butang.

Kemudian pilih Tidak Mengikat dan pilih butang yang ingin anda berikan dari Laluan.

Jika anda ingin menambah lebih banyak, pilih "Tambah Mengikat" dari butang +.

Tambah seberapa banyak yang anda perlukan. Oleh kerana ia dianggap sebagai butang, papan kekunci boleh ditetapkan dengan cara yang sama seperti pengawal permainan.

Apabila semua tetapan selesai, klik "Simpan Aset" untuk menyimpan. Anda boleh menutup tetingkap ini.

Akhirnya, dengan fail inputactions projek (dalam kes ini, fail InputActionSample yang anda buat sebelum ini), tandakan "Jana C# Kelas" dalam pemeriksa. Parameter akan ditambah, tetapi klik butang "Terapkan" seperti sedia ada.

Ini akan menjana fail skrip dengan nama yang sama. Ia mengandungi kelas yang berguna untuk menggunakan peta tindakan daripada program.

Cara menerima maklumat input

Terdapat beberapa cara untuk menerima input berdasarkan peta tindakan. Petua ini menerangkan tiga corak, tetapi lebih baik untuk memberi tumpuan kepada salah satu daripadanya apabila benar-benar membuat permainan. Jika anda menggunakannya secara berasingan, ia akan menyusahkan untuk diuruskan.

Selain itu, jika anda menggunakan berbilang kaedah penerimaan input dalam satu adegan, pemprosesan mungkin bertentangan secara dalaman dan tidak berfungsi dengan betul.

Terima maklumat input dalam Hantar Mesej

Kaedah pertama di sini ialah cara menerima maklumat input dalam "Hantar Mesej".

Kali ini, saya ingin memaparkan maklumat yang dimasukkan dalam teks, jadi saya akan meletakkan objek teks.

Juga, kerana petua ini akan cuba mendapatkan pelbagai maklumat input, kami akan membuat objek kosong untuk menetapkan komponen secara berasingan. Nama itu boleh jadi apa sahaja.

Seterusnya, tambah komponen Input Pemain pada objek kosong. Input Pemain ialah komponen penting untuk menyambungkan peta tindakan dan skrip.

Dalam "Tambah Komponen", terdapat "Input Pemain" dalam kategori "Input", jadi tambahkannya.

Setelah komponen Input Pemain ditambahkan, tetapkan peta tindakan yang anda buat dalam "Tindakan". Lepaskannya dari projek atau pilih dari ikon + ke kanan.

Sahkan bahawa Peta Lalai ialah peta yang anda cipta dalam peta tindakan.

Sahkan bahawa Kelakuan adalah "Hantar Mesej".

Seterusnya, buat skrip. Nama fail boleh menjadi apa-apa, tetapi di sini InputSendMessage ia adalah .

Skrip kelihatan seperti ini:

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}";
  }
}
  • Objek mempunyai lampiran Input Pemain yang mengesetkan Hantar Mesej
  • Mewarisi daripada MonoBehaviour

Sekiranya syarat-syarat dipenuhi, maka jika anda menentukan kaedah yang dipanggil "OnXXXXXXXX", Kaedah sasaran akan dipanggil apabila operasi tindakan tertentu dilakukan. "XXXXXXXX" ialah nama Tindakan yang dibuat dalam peta tindakan. Di sini, kami telah mencipta tindakan "Move" dan "Attack", jadi nama kaedah adalah "OnMove" dan "OnAttack", masing-masing.

OnMove Anda boleh mendapatkan jumlah yang dimasukkan dari hujah InputValue . Oleh kerana Jenis Kawalan ditetapkan kepada "Vektor 2", nilai InputValue.Get<Vector2> input akan diterima dalam .

OnAttackInputValue.isPressed Anda boleh mendapatkan sama ada anda menekan juga.

Selepas anda menyimpan skrip, lampirkannya pada objek yang mempunyai komponen Input Pemain. Setkan objek teks untuk paparan juga.

Jalankan permainan dan lihatlah. Kali ini, saya telah memasukkan definisi pad permainan dan papan kekunci, jadi ia harus berfungsi tidak kira yang mana anda beroperasi.

Seperti yang anda lihat apabila anda memindahkannya, anda dapat melihat bahawa kaedah itu dipanggil hanya apabila terdapat perubahan nilai dari keadaan sebelumnya. Sebagai contoh, semasa memindahkan kayu ke kiri, ia dipanggil berfikiran tunggal, tetapi tidak ke kiri (- OnMove 1,0). OnMove Butang Serangan juga bertindak balas hanya apabila ia ditekan, dan jika ditekan dan dipegang, kaedah itu tidak dipanggil.

Oleh itu, saya berpendapat bahawa penggunaan yang ideal bukan untuk melakukan pemprosesan permainan apabila OnXXXXXXXX dipanggil, tetapi untuk menyimpan hanya kandungan input dan menggunakan nilai-nilai tersebut dalam pemprosesan kemas kini permainan.

Dengan cara ini, dalam keadaan semasa, ia tidak dipanggil apabila butang dilepaskan, jadi tidak mungkin untuk menentukan bila OnAttack butang dilepaskan. Untuk bertindak balas terhadap perkara ini, pilih tindakan Serangan yang mentakrifkan butang dalam tetapan peta tindakan dan tambah "Tekan" daripada "Interaksi". Selepas itu, tetapkan Kelakuan Pencetus Akhbar tambahan kepada "Tekan Dan Lepaskan" dan simpannya.

Apabila dilaksanakan, anda dapat melihat yang dipanggil walaupun OnAttack butang dilepaskan. isPressed false Oleh kerana ia menjadi , ia juga mungkin untuk menentukan sama ada ia adalah masa pelepasan.

Dengan cara ini, sila padamkan interaksi ini kerana ia tidak akan digunakan pada masa akan datang.

Terima input dengan Acara Perpaduan Invoke

Cara kedua untuk menerima input ialah Acara Perpaduan Invoke, jadi mari kita cuba ini. Seperti yang dinyatakan di atas, menggunakan pelbagai kaedah input boleh menyebabkan pemprosesan yang bercanggah, jadi jika pemprosesan lain diaktifkan, lumpuhkannya.

Mula-mula, letakkan objek teks supaya maklumat input boleh dipaparkan.

Acara Perpaduan Invoke mencipta objek kosong yang melakukan operasi berkaitan.

Tambah Input > Input Pemain kepada objek yang kosong.

Setkan fail peta tindakan yang anda cipta untuk Tindakan (dalam kes ini, InputActionSample) dan setkan Peta Tindakan yang anda cipta (dalam kes ini, SideScrollActionMap) kepada Peta Lalai. Tetapkan Kelakuan untuk Memohon Acara Perpaduan.

Buat skrip. Nama itu sewenang-wenangnya, tetapi dalam kes InputInvokeUnityEvents ini ia adalah .

Skrip kelihatan seperti ini:

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

Nama OnMoveOnAttack kaedah yang dipanggil apabila pengguna berinteraksi dengannya adalah , seperti dalam hal Hantar Mesej. Dalam Acara Perpaduan Invoke, anda boleh menetapkan nama kaedah ini sesuka hati.

Apabila masing-masing dipanggil, ia diluluskan sebagai InputAction.CallbackContext hujah, jadi anda boleh mendapatkan status input dari sana. Jika anda menetapkan "nilai" dalam tindakan itu, anda boleh menerimanya dalam kaedah itu, dan jika anda menetapkan ReadValueAsButton "butang", anda ReadValue boleh menerimanya dalam kaedah tersebut.

Selepas menyimpan skrip, lampirkan Input Pemain pada objek yang anda setkan dan setkan objek teks paparan.

Seterusnya, kembangkan "Acara" dan "Nama Peta Tindakan (SideScrollActionMap)" dalam Input Pemain dan anda sepatutnya melihat tindakan "Alih" dan "Serangan" yang anda buat.

Mula-mula, klik butang + pada Alih untuk menambahnya.

Objek di sudut bawah kiri ialah objek anda sendiri dan Fungsi disetkan kepada kaedah yang baru sahaja anda cipta OnMove .

Konfigurasikan peristiwa Serangan juga.

Jalankan permainan untuk melihat bagaimana ia berfungsi.

Pada asasnya, ia dipanggil hanya apabila nilai yang sama seperti Hantar Mesej berubah, tetapi atas sebab tertentu kaedah itu boleh dipanggil dua kali pada masa yang sama. Saya tidak tahu puncanya, tetapi saya fikir ia mungkin kerana proses permulaan dan proses berterusan berjalan pada masa yang sama. Walau bagaimanapun, saya fikir tidak ada masalah jika anda hanya menyimpan nilai yang dimasukkan seperti dalam kes Hantar Mesej dan melakukan pemprosesan permainan sebenar secara berasingan dalam proses Kemas Kini.

Menggunakan skrip yang dijanakan secara automatik untuk menerima maklumat input

Seksyen ketiga menerangkan cara mendapatkan maklumat input menggunakan skrip yang dijana daripada fail peta tindakan.

Oleh kerana terdapat kemungkinan konflik dengan proses pemerolehan lain, sila lumpuhkan proses pemerolehan lain.

Meletakkan objek teks untuk memaparkan maklumat input.

Juga, cipta objek kosong untuk mendapatkan maklumat input. Artikel ini menggunakan skrip yang dijana secara automatik, jadi anda tidak perlu menambah Input Pemain.

Skrip yang dijana secara automatik daripada peta tindakan hanyalah pustaka, jadi buat skrip kawalan yang berasingan. Nama itu sewenang-wenangnya, tetapi dalam kes InputScript ini ia adalah .

Skrip kelihatan seperti ini:

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

Tentukan kelas InputActionSample yang dijana secara automatik daripada peta tindakan dalam medan. Kelas ini mentakrifkan setiap tindakan yang ditetapkan dalam peta tindakan dan anda boleh menetapkan peristiwa yang dipanggil apabila tindakan tersebut dilakukan.

Awake Dalam kaedah ini, InputActionSample satu contoh dicipta dan acara yang dipanggil pada masa tindakan ditetapkan. Apabila OnMoveanda melakukan operasi ini, kaedah , OnAttack kini dipanggil.

Walau bagaimanapun, kerana kami hanya menetapkan acara di sini, kami OnEnable perlu memanggil kaedah Enable apabila dipanggil untuk membolehkan peta tindakan.

Juga, kerana tingkah laku input pengguna dianggap sebagai operasi global, Untuk mengelakkan OnDisable peta tindakan daripada melakukan tambahan selepas objek ini tidak sah, kami memanggil kaedah dalam kaedah Disable untuk menyahdayakannya.

Selepas menyimpan skrip, lampirkannya pada objek kosong yang anda cipta dan setkan objek teks untuk paparan.

Jalankan permainan untuk melihat bagaimana ia berfungsi.

Seperti yang anda lihat, kaedah ini tidak dipanggil apabila OnMove operasi Bergerak menjadi (0, 0). Saya tidak pasti mengapa, tetapi nampaknya acara yang dilakukan hanya benar-benar mengambil acara dengan ketukan kekunci diaktifkan.

Dengan cara ini, jika anda tidak menetapkan Interaksi dalam peta tindakan untuk Serangan, ia tidak akan dipanggil apabila OnAttack anda melepaskan butang.

Untuk canceled mengendalikan ini, anda perlu menyediakan acara. Jika anda tidak mahu melakukan pemprosesan khas pada (0, 0), anda boleh memanggil kaedah seperti itu OnMove . Perkara yang sama berlaku untuk Serangan.

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);   // 追加
}

Jalankan dan sahkan bahawa Alih:(0, 0) atau Serangan:Palsu muncul.