Spawn dan Collision

Pada bagian ketiga ini, kita akan membahas mengenai cara spawning objek baru ketika game sedang berlangsung. Serta cara membuat interaksi antara satu objek dengan objek lain ketika bertemuan menggunakan sistem collision yang sudah ada pada Unity. Selain kedua hal itu, kita akan mengenal beberapa konsep baru yang ada pada Unity seperti prefab, physics, dan lain sebagainya.

Prefab

Di Unity, umumnya game object selalu dikaitkan dengan suatu scene, seperti yang dijelaskan pada bagian pertama, dimana scene dapat tersusun dari beberapa game object. Namun, suatu game object bisa dibentuk menjadi sebuah asset, sehingga tersimpan diluar scene, dan dapat digunakan di scene manapun tanpa perlu membuat ulang game object tersebut dan menyusun component-nya lagi di scene baru. Game object yang berbentuk asset ini secara umum dikenal sebagai prefab. Salah satu kegunaan dari prefab, selain yang dijelaskan sebelumnya adalah sebagai template game object yang nantinya bisa digunakan dalam spawning.

Informasi lebih lanjut mengenai prefab pada Unity bisa dilihat disini.

Prefab Enemy

Object Spawning

Dalam game development, object spawning mengacu pada istilah pembuatan suatu objek baru ketika game sedang berlangsung. Di Unity sendiri object spawning bisa dilakukan dengan cara memanggil method Instantiate() menggunakan template dari suatu objek yang bisa berupa game object maupun prefab.

Informasi lebih lanjut mengenai method Instantiate() bisa dilihat disini.

Component Spawner

Pada percobaan kali ini, kita akan membuat component baru yang akan digunakan untuk melakukan spawning dari suatu objek dalam interval tertentu. Untuk itu, pertama, buat C# script baru dengan nama Spawner.

Buka C# script tersebut dan ubah isi dari class Spawner sebagai berikut:

public class Spawner : MonoBehaviour
{
    public GameObject prefab;
    public float spawnInterval = 1;

    float time = 0;

    void Update()
    {
        time += Time.deltaTime;
        if (time >= spawnInterval) {
            time -= spawnInterval;

            if (prefab != null) {
                Instantiate(prefab, transform.position, transform.rotation);
            }
        }
    }
}

Penjelasan singkat dari baris program diatas, program tersebut akan menambah nilai dari variabel time sebesar Time.deltaTime. Baris program seperti diatas secara umum digunakan di Unity sebagai timer sederhana yang akan memanggil fungsi yang ada di dalam blok if jika waktunya sudah terpenuhi (dalam hal ini yang dimaksud dengan waktu adalah waktu dari spawnInterval).

Kemudian program akan menge-_check_ jika variabel prefab ada (kembali untuk menghindari runtime error), dan memanggil method Instantiate() menggunakan parameter prefab yang nantinya diset di Inspector Window dan parameter posisi serta rotasi dari objek yang memanggil method Instantiate() itu sendiri._

Menggunakan Component Spawner

Physics

Kebanyakan game yang ada saat ini, baik itu yang berbentuk 3D maupun 2D sudah menerapkan physics dalam game yang dibuat. Jadi untuk pergerakan dari objek pada game tidak hanya dilakukan dengan mengubah nilai dari transformasi secara linear, namun juga dengan menerapkan prinsip fisika seperti inertia, gravitasi, dan lain sebagainya.

Informasi lebih lanjut mengenai physics pada Unity bisa dilihat disini.

Component Rigidbody 2D

Secara sederhana, rigidbody pada Unity merupakan istilah yang digunakan untuk menunjukkan objek yang akan dipengaruhi oleh physics. Di Unity sendiri terdapat perbedaan antara physics untuk game 3D dengan 2D. Oleh karena itu terdapat dua macam bentuk component dari rigidbody, yakni Rigidbody untuk game 3D dan Rigidbody 2D untuk game 2d. Karena game yang kita buat merupakan game 2D, disini kita akan menggunakan rigidbody menggunakan component Rigidbody 2D.

Informasi lebih lanjut mengenai component Rigidbody 2D bisa dilihat disini.

Mengganti Pergerakan Transform Dengan Rigidbody 2D

Sebelumnya kita sudah membuat component Movement Input dan Up Movement yang digunakan untuk menggerakkan objek dengan mengubah transformasi. Kali ini kita akan mengubah isi dari kedua component tersebut sehingga alih-alih menggunakan transformasi sederhana, pergerakan dari game object akan dipengaruhi oleh physics untuk mendapatkan hasil yang lebih baik.

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

public class MovementInput : MonoBehaviour
{
    ...

    Rigidbody2D rigidbody2d;

    void Start()
    {
        rigidbody2d = GetComponent<Rigidbody2D>();
    }

    // void Update()
    void FixedUpdate()
    {
        ...

        // Vector3 translation = new Vector3(inputX, inputY, 0);
        Vector2 translation = new Vector2(inputX, inputY);

        ...

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

        if (rigidbody2d != null) {
            rigidbody2d.velocity = translation * Time.deltaTime * speed;
        }
    }
}

Penjelasan singkat dari baris program diatas, program akan menyimpan referensi dari component Rigidbody 2D karena berbeda dengan component Transform, secara default referensi dari component Rigidbody 2D tidak disimpan pada class MonoBehaviour. Lalu fungsi Update() harus diganti dengan FixedUpdate() karena perhitungan yang dipengaruhi oleh physics pada Unity harus ditaruh disana. Kemudian kita harus mengganti bentuk dari variabel translation menjadi Vector2 karena Rigidbody 2D hanya bisa berkerja dengan perhitungan 2D. Dan terakhir, alih-alih melakukan translasi pada component Transform, program akan mengubah nilai velocity dari rigidbody2d menggunakan perhitungan yang sama.

Setelah selesai, simpan baris program tersebut. Kemudian buka C# script dari component Up Movement dan ubah isi dari class UpMovement sebagai berikut:

public class UpMovement : MonoBehaviour
{
    public float speed = 1;
    Rigidbody2D rigidbody2d;

    void Start()
    {
      rigidbody2d = GetComponent<Rigidbody2D>();
    }

    // void Update()
    void FixedUpdate()
    {
        // Vector3 translation = new Vector3(0, 5, 0);
        // transform.Translate(translation * Time.deltaTime);

        if (rigidbody2d != null) {
            rigidbody2d.velocity = Vector2.up * Time.deltaTime * speed;
        }
    }
}

Penjelasan singkat dari baris program diatas, program memiliki kesamaan dengan program dari component Movement Input seperti yang sudah dijelaskan sebelumnya. Selain itu, program juga mulai menggunakan public property sehingga nantinya kecepatan dari objek bisa diatur lebih mudah pada Inspector Window seperti yang dijelaskan pada bagian kedua.

Sebagai tambahan, Vector2.up merupakan salah satu member variabel dari class Vector2 yang memiliki nilai yang sama dengan new Vector2(0, 1). Informasi lebih lanjut mengenai class Vector2 bisa dilihat disini.

Setelah selesai, simpan baris program tersebut.

Menggunakan Rigidbody

Tag

Sesuai dengan namanya, tag merupakan istilah yang digunakan di Unity untuk memberi label pada suatu game object, sehingga kita bisa menggolongkan game object menjadi beberapa jenis berdasarkan tag yang diberikan. Pada bahasan kali ini kita akan menggunakan tag terutama untuk membedakan antara objek yang berjenis player dengan enemy yang nantinya akan digunakan lebih lanjut dalam bagian collision.

Informasi lebih lanjut mengenai tag pada Unity bisa dilihat disini

Mengatur Tag

Collider

Collider pada Unity merupakan jenis component yang memiliki kegunaan untuk mendeteksi sentuhan dari suatu objek dengan objek yang lain. Secara umum terdapat dua bentuk collider di Unity, yakni collision itu sendiri dan trigger. Perbedaannya terletak pada seberapa detail informasi yang diperlukan ketika dua objek saling bersentuhan. Pada trigger informasi yang diberikan hanya berupa objek yang disentuh, sedangkan pada collision informasi yang diberikan akan lebih detail lagi seperti letak sentuhan, dan seberapa banyak objek yang bersentuhan.

Informasi lebih lanjut mengenai collider pada Unity bisa dilihat disini

Membuat Component Destroy On Contact

Pada percobaan kali ini kita akan membuat component baru yang digunakan untuk menghapus suatu objek jika objek tersebut bersentuhan dengan objek lain yang memiliki tag tertentu. Untuk itu, pertama, buat C# script baru dengan nama DestroyOnContact.

Buka C# script tersebut dan ubah isi dari class DestroyOnContact sebagai berikut:

public class DestroyOnContact : MonoBehaviour
{
    public string contactTag;

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.tag == contactTag)
        {
            Destroy(gameObject);
        }
    }
}

Penjelasan singkat dari baris program diatas, fungsi OnTriggerEnter2D() akan dipanggil jika suatu collider bersentuhan dengan collider yang lain. Dan jika objek dari collider tersebut memiliki tag seperti yang ditentukan di contactTag, maka program akan menghapus game object itu sendiri.

Sebagai catatan, OnTriggerEnter2D() merupakan salah satu bentuk fungsi event yang ada pada class MonoBehaviour, sama seperti fungsi Start(), Update(), dan lain sebagainya. Informasi lebih lanjut mengenai fungsi event yang ada pada MonoBehavior bisa dilihat disini.

Menggunakan Component Destroy On Contact

Pada tahap ini, ketika objek Player bersentuhan dengan objek Enemy maka kedua objek tersebut akan secara otomatis terhapus dari game. Hal ini sesuai dengan cara kerja dari component Destroy On Contact seperti yang dijelaskan sebelumnya.

Menembak Peluru

Game yang sudah kita buat sudah berjalan cukup lancar, namun akan terasa membosankan jika tantangan yang ada hanyalah menghindari gerakan dari musuh. Untuk itu kita akan menerapkan fitur baru yang ada pada game yang kita buat sehingga kedua objek player maupun enemy memiliki kemampuan untuk menembakkan peluru.

Sebagai catatan, untuk mempersingkat waktu, component yang akan digunakan pada tahap ini sebelumnya sudah dibuat dan siap untuk digunakan. Detail dari cara kerja component tersebut tidak akan dibahas disini, namun bisa ditanyakan di lain waktu.

Component Enemy Behavior

Component Shoot Input

Kesimpulan

Dari bagian ketiga ini kita telah membahas mengenai cara melakukan object spawning ketika game sedang berlangsung serta interaksi yang dapat dilakukan dari dua objek berbeda ketika keduanya bersentuhan. Selain itu kita juga mengenal beberapa konsep baru di Unity seperti detail dari sistem Physics sebagai alternatif cara menggerakkan objek selain dengan cara transformasi serta beberapa konsep dasar seperti prefab untuk menyimpan game object sebagai asset dan tag untuk menggolongkan game object menjadi jenis tertentu.

Pada bagian selanjutnya kita akan mematangkan lagi game yang sudah kita buat dengan menambahkan scene baru untuk keperluan menu, menambahkan tatap muka pada game, serta menerapkan sistem score pada game yang kita buat.

Lanjut bagian keempat, Navigasi Scene