Input dan Gerakan

Pada bagian kedua dari modul ini, kita akan membahas mengenai interaksi pemain dengan game melalui input yang diberikan oleh pemain. Serta bagaimana sistem akan merespon input dari pemain tersebut, yang mana salah satunya adalah dengan menggerakkan objek yang dikendalikan oleh pemain. Selain soal input dan gerakan, pada bagian ini kita juga akan menyinggung beberapa hal lain yang akan membantu pengembangan game ini dari sisi input dan gerakan seperti soal public property, sprite, dan lain sebagainya.

Input

Salah satu keunggulan dari Unity adalah sifatnya yang cross platform. Karena itu juga, Unity secara penuh mendukung berbagai macam jenis input yang bisa digunakan seperti keyboard, joystick, touch screen, hingga controller VR dan AR. Pada bagian ini, kita akan membahas lebih lanjut mengenai bagaimana input di Unity bekerja, terutama soal input yang menggunakan keyboard dan mouse.

Informasi lebih lanjut mengenai input pada Unity bisa dilihat disini.

Input Manager

Di Unity, input secara umum akan diperlakukan sebagai axis, termasuk untuk input yang seharusnya berupa button. Axis sendiri merupakan representasi input yang memiliki dua arah yang saling berlawanan (negatif dan positif), biasanya digunakan sebagai input arah, seperti pada tombol left/right atau axis pada joystick. Bagian yang mengatur input pada Unity sendiri adalah Input Manager yang bisa diakses melalui menu Edit -> Project Settings... -> Input Manager.

Tampilan **Input Manager**

Dengan adanya Input Manager, kita bisa mengatur berbagai macam input dalam bentuk axis yang dibutuhkan pada game yang kita buat, seperti mengubah nama axis maupun mengubah tombol yang mempengaruhi axis tersebut. Seperti pada contoh default, kita bisa mengetahui jika axis Horizontal dipengaruhi oleh tombol left dan right sedangkan axis Vertical dipengaruhi oleh tombol down dan up.

Informasi lebih lanjut mengenai Input Manager pada Unity bisa dilihat disini.

Mengendalikan Pergerakan Objek Dengan Keyboard

Pada percobaan kali ini, kita akan membuat component baru yang akan digunakan untuk mengendalikan pergerakan objek selama game sedang berlangsung menggunakan keyboard.

Membuat Component Movement Input

Buat C# script baru dan beri nama MovementInput, kemudian buka C# script tersebut dan ubah isi dari fungsi Update() sebagai berikut:

void Update()
{
    float inputX = Input.GetAxisRaw("Horizontal");
    float inputY = Input.GetAxisRaw("Vertical");

    Vector3 translation = new Vector3(inputX, inputY, 0);
    translation.Normalize();

    transform.Translate(translation * Time.deltaTime);
}

Penjelasan singkat dari baris program diatas, program akan mengambil nilai dari axis Horizontal dan Vertical secara raw menggunakan fungsi GetAxisRaw() dan kemudian menyimpannya ke dalam variabel inputX dan inputY secara berurutan. Istilah raw pada GetAxisRaw() sendiri menandakan bahwa input yang diberikan tidak akan mengalami smoothing.

Sebagai catatan, GetAxisRaw() merupakan static method dari class Input, sehingga bisa dipanggil langsung tanpa perlunya instansi dari class tersebut. Informasi lebih lanjut mengenai class Input bisa dilihat disini.

Kemudian dari kedua nilai input yang didapatkan, dibentuklah Vector3 baru yang kemudian di-normalize agar gerakan diagonal dari objek tidak lebih cepat dari gerakan yang lain. Setelah itu, fungsi Translate() akan dipanggil menggunakan nilai Vector3 yang sudah dibuat sebelumnya dikalikan dengan Time.deltaTime.

Setelah selesai, simpan baris program tersebut.

Menggunakan Component Movement Input

Public Property

Pada bagian sebelumnya, kita telah membuat component Movement Input untuk menggerakkan objek yang kita inginkan. Namun, gerakan dari component yang telah kita buat terasa cukup lambat, dan kita juga tidak bisa mengatur kecepatan dari objek yang kita kendalikan sesuai dengan keinginan kita. Oleh karena itu, Unity mengenal sebuah istilah yang bernama public property. Secara umum, property sendiri digunakan untuk mendefiniskan variabel yang dimiliki oleh suatu class. Dengan menjadikan suatu property sebagai public, maka nilai dari property tersebut bisa diubah secara langsung melalui Inspector Window tanpa perlu mengubahnya melalui C# script.

Buka kembali C# script dari component Movement Input dan ubah isi dari class MovementInput sebagai berikut:

public class MovementInput : MonoBehaviour
{
    public float speed = 1;

    ...

    void Update()
    {
        ...

        transform.Translate(translation * Time.deltaTime * speed);
    }
}

Penjelasan singkat dari baris program diatas, nilai translasi sebelumnya dari component Movement Input akan dikalikan dengan public property speed yang secara default bernilai 1. Nantinya, besar dari translasi (kecepatan dari objek) akan dipengaruhi oleh nilai dari public property tersebut.

Setelah selesai, simpan baris program tersebut. Kemudian pada component Movement Input akan terdapat input field baru dengan nama Speed, nilai dari input field tersebut bisa diubah sesuai dengan keinginan. Hasilnya ketika game sedang berlangsung, kecepatan dari game object yang dikendalikan oleh pemain akan semakin lambat maupun semakin cepat sesuai dengan nilai Speed yang diberikan.

_Public property_ pada _component_ `Movement Input`

Mengendalikan Perputaran Objek Dengan Mouse

Pada percobaan kali ini, kita akan membuat component baru yang akan digunakan untuk mengendalikan perputaran objek berdasarkan posisi dari mouse selama game sedang berlangsung.

Membuat Component Rotation Input

Buat C# script baru dan beri nama RotationInput, kemudian buka C# script tersebut dan ubah isi dari fungsi Update() sebagai berikut:

void Update()
{
    Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    Vector3 mouseDirection = mousePosition - transform.position;

    float angle = Mathf.Atan2(mouseDirection.y, mouseDirection.x) * Mathf.Rad2Deg;

    transform.eulerAngles = new Vector3(0, 0, angle);
}

Penjelasan singkat dari baris program diatas, inti dari program tersebut adalah mengubah nilai input dari posisi mouse yang awalnya berdasarkan posisi screen (2D) menjadi posisi world (3D) dan menyimpannya ke dalam variabel mousePosition. Kemudian dihitung selisih dari posisi mouse dengan posisi dari objek dan disimpan dalam variabel mouseDirection dalam bentuk vektor. Dari vektor tersebut, kemudian dihitung nilai dari sudut tersebut menggunakan perhitungan fungsi atan2 yang nantinya akan di-_set_ ke nilai eulerAngles (atau Rotation) dari component Transform.

Atan2, dikenal juga sebagai 2-argument arctangent, merupakan fungsi yang digunakan untuk mendapatkan nilai sudut berdasarkan arah x dan y. Berbeda dengan atan yang hanya menghasilkan sudut 180 derajat, atan2 bisa digunakan untuk menghasilkan sudut hingga 360 derajat.

Setelah selesai, simpan baris program tersebut.

Menggunakan Component Rotation Input

Sprite

Pada game development, istilah sprite secara umum merujuk pada grafik 2D, baik itu berupa grafik untuk player, partikel, animasi, tatap muka, dan lain sebagainya. Unity sendiri sejak awal sudah mendukung istilah sprite (dengan nama lain texture). Walaupun awalnya Unity fokus pada pengembangan 3D, tetapi grafik 2D secara umum sudah digunakan, terutama untuk texture pada model 3d dan untuk grafik pada tatap muka.

Informasi lebih lanjut mengenai sprite pada Unity bisa dilihat disini.

Menambahkan Sprite Pada Game Object

Mengatur Sprite Untuk Rotasi

Jika kita lihat, sprite Player yang kita gunakan sebelumnya terdapat pada folder Sprites. Bentuk dari sprite Player sendiri awalnya bukan sprite satuan, tetapi dalam bentuk spritesheet yang terdiri dari berbagai macam sprite (disini setiap sprite merepresentasikan arah hadap dari karakter player).

Tampilan lengkap _sprite_ `Player`

Jika kita klik tombol panah lingkaran maka akan terlihat isi dari spritesheet tersebut yang sudah terbagi menjadi beberapa sprite dari Player_0 sampai Player_7.

Tampilan lengkap _sprite_ `Player`

Secara default, setiap grafik pada Unity akan diperlakukan sebagai sprite tunggal. Untuk menjadikan suatu grafik sebagai spritesheet dan membaginya menjadi beberapa sprite maka dibutuhkan cara tersendiri menggunakan Sprite Editor. Informasi lebih lanjut mengenai penggunaan Sprite Editor bisa dilihat disini.

Masalah dari program sebelumnya adalah alih-alih mengganti sprite untuk menampilkan arah hadap dari karakter player, program malah merubah rotasi dari keseluruhan sprite. Untuk itu disini kita akan mengatasi masalah itu dengan component Sprite Rotation yang sudah ada pada asset dan siap untuk digunakan.

Menggunakan Component Sprite Rotation

Menghubungkan Component Sprite Rotation dengan Rotation Input

Sebelumnya kita sudah memahami kegunaan dari component Sprite Rotation. Kali ini kita akan menghubungkannya dengan component Rotation Input sehingga alih-alih mengubah rotasi dari component Transform, component Rotation Input akan mengubah nilai Rotation dari component Sprite Rotation.

Buka kembali C# script dari component Rotation Input dan ubah isi dari class Rotation Input sebagai berikut:

public class RotationInput : MonoBehaviour
{
    SpriteRotation spriteRotation;

    void Start()
    {
      spriteRotation = GetComponent<SpriteRotation>();
    }

    void Update()
    {
        ...

        // transform.eulerAngles = new Vector3(0, 0, angle);

        if (spriteRotation != null) {
            spriteRotation.rotation = angle;
        }
    }
}

Penjelasan singkat dari baris program diatas, program akan mengambil referensi dari component Sprite Rotation dan menyimpannya ke variabel spriteRotation. Ketika update, program akan mengecek jika component Sprite Rotation ada (tidak null, untuk menghindari runtime error) dan jika ada, program akan mengubah nilai rotation dari component tersebut dengan nilai angle dari perhitungan sebelumnya.

GetComponent<T>() merupakan salah satu method yang ada di class MonoBehavior (parent class dari class RotationInput). Method ini memiliki kegunaan untuk mengambil referensi class dari component yang ada pada suatu game object. Informasi lebih lanjut dari method GetComponent<T>() bisa dilihat disini.

Setelah selesai, simpan baris program tersebut dan coba jalankan kembali game untuk melihat hasilnya. Pada tahap ini, ketika mouse digerakkan, sprite dari objek Player akan berubah menghadap ke arah mouse sesuai dengan perilaku SpriteRotation dan RotationInput yang ada sebelumnya.

Pastikan component RotationInput sudah di-_set_ kembali sebagai enable agar component bekerja.

Kesimpulan

Dari bagian kedua ini kita telah mengenal bagaimana cara untuk membuat component yang dapat digunakan untuk memanipulasi objek menggunakan input yang tersedia. Selain itu kita juga mempelajari beberapa konsep tambahan dari Unity seperti kegunaan public property yang bisa digunakan untuk mengubah variabel secara langsung pada *Inspector Window tanpa mengubah program serta menggunakan sprite untuk mempercantik tampilan dari game object.

Pada bagian selanjutnya kita akan membahas lebih lanjut mengenai spawn yang bisa digunakan untuk menambahkan game object secara otomatis selama game sedang berlangsung dan collision yang nantinya digunakan untuk mengatur interaksi dari satu objek dengan objek lain ketika bertemu.

Lanjut bagian ketiga, Spawn dan Collision