Sekitar beberapa hari yang lalu, saya iseng nyobain membuat mini game yang judulnya Keep Our Distance! Jadi ini adalah sebuah mini game yang mengambil konsep tentang physical distancing atau pembatasan jarak fisik. Dimana pemain akan menggerakkan sebuah emoji untuk menghindari emoji lain yang dimunculkan secara acak.

Ketika emoji pemain menyentuh emoji lain yang sedang lewat, maka emoji tersebut akan kehilangan life point sampai akhirnya mati dan game over! Kurang lebih seperti ini gambaran permainannnya.

Cuplikan Gameplay dari Mini Game Keep Our Distance!

Dari membuat mini game tersebut, saya mendapatkan banyak ilmu baru. Salah satunya adalah tentang bagaimana spawn object atau memunculkan objek pada lokasi yang acak seperti contoh yang ada di cuplikan gameplay yang ada diatas. Terlihat emoji yang menggunakan masker muncul secara acak.

Jadi disini kita bakal coba membuat ulang itu dengan menggunakan konsep yang berbeda. Yaitu membuat animasi asteroid yang muncul secara acak di luar angkasa.

Kira-kira hasilnya bakal kayak gini.

Asteroids in Space!

Oiya kita membuat ini dengan menggunakan Unity3D. Unity3D adalah sebuah game engine yang sudah banyak digunakan oleh para game developer untuk membuat game. Dan bahasa pemrograman yang di dukung oleh Unity3D adalah C# atau C-sharp.

Pertama, silahkan buat projek 2D baru di Unity3D. Dan tampilan awalnya akan jadi seperti ini (Saya menggunakan versi 2018.4).

Tampilan awal setelah create new project di Unity3D

Kemudian kita membuat folder baru yang kita beri nama images dan memasukkan asset berupa gambar latar luar angkasa dan asteroid yang saya dapatkan disini.

Selanjutnya, membuat background luar angkasa dengan cara buat Image UI pada Scene Hierarchy dan set Render Mode menjadi Screen Space - Camera lalu drag objek main camera ke dalam properti Render Camera pada komponen yang ada di objek Canvas. Kurang lebih hasilnya jadi seperti ini.

Lalu pada set anchor preset menjadi stretch to entire screen dengan menekan alt dan memilih preset yang ada di pojok kanan bawah pada komponen Rect Transform dan drag gambar latar luar angkasa yang sudah diunduh sebelumnya ke properti Source Image pada komponen Image (Script) yang ada pada objek Image. Kurang lebih seperti ini.

Jangan lupa buat resolusi baru dengan ukuran 1366x768 pada tab game.

Dan akhirnya selesai membuat background luar angkasa.

Selanjutnya membuat objek asteroid dengan cara klik kanan pada Scene Hierarchy lalu pilih Create Empty. maka akan muncul objek baru dan ganti namanya menjadi asteroids. Dan juga membuat satu lagi objek dengan nama GameManager.

Lanjut, pada inspector milik asteroids tambah komponen baru yang namanya Sprite Renderer. Dan drag gambar asteroids yang ada di folder images ke properti Sprite. Dan tambah dua komponen lagi berupa Circle Collider 2D dan Rigidbody2D.

Pada komponen Circle Collider 2D ubah properti radius menjadi 1.3 dan set properti Gravity Scale menjadi 0 pada komponen Rigidbody2D.

Hasilnya bakal seperti ini.

Lalu buat folder baru dengan nama Scripts dan create new C# Script baru didalamnya dengan nama SpawnAsteroids. Dan buka file tersebut dengan menggunakan kode editor, disini saya menggunakan Visual Studio Code.

Lalu kita tambahkan kode ini kedalamnya.

public GameObject asteroidsPrefab;
public float respawnTime = 5f;
public Vector2 screenBounds;

// Start is called before the first frame update
void Start()
{
    screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
    StartCoroutine(asteroidsWave());
}

private void spawnAsteroids() {
    GameObject a = Instantiate(asteroidsPrefab) as GameObject;
    a.transform.position = new Vector2(screenBounds.x + 1, Random.Range(-screenBounds.y, screenBounds.y));
}

IEnumerator asteroidsWave() {
    while(true) {
        yield return new WaitForSeconds(respawnTime);
        spawnAsteroids();
    }
}

Iya iya, baca dulu penjelasan dari aku ya :)

public GameObject asteroidsPrefab;
public float respawnTime = 5f;
public Vector2 screenBounds;

Pertama, kita buat 3 variabel ini. variabel pertama digunakan untuk menampung objek prefab dari asteroid. Yang kedua itu untuk digunakan untuk menampung nilai dari waktu respawn si asteroid. Dan yang terakhir adalah untuk menampung resolusi dari layar.

private void spawnAsteroids() {
    GameObject a = Instantiate(asteroidsPrefab) as GameObject;
    a.transform.position = new Vector2(screenBounds.x + 1, Random.Range(-screenBounds.y, screenBounds.y));
}

Kedua, kita buat method untuk memunculkan asteroid pada lokasi yang acak. Jadi langkah pertama kita buat sebuah objek asteroid baru dengan meng-clone dari prefab yang sudah dibuat sebelumnya menggunakan method Instantiate.

Dan mengakses properti posisi dari asteroid baru tersebut dan menambahkan nilai baru menggunakan objek Vector2 dengan properti x = x dari variabel screenBounds + 1 supaya asteroid baru tersebut muncul disebelah kiri luar layar. Dan memunculkan secara acak menggunakan class Random dengan range nya adalah dari nilai bawah sampai nilai atas y. Dimasukkan kedalam properti y dari objek Vector2 tadi.

IEnumerator asteroidsWave() {
    while(true) {
        yield return new WaitForSeconds(respawnTime);
        spawnAsteroids();
    }
}

Ketiga, kita akan membuat si asteroid baru yang udah dibuat itu akan muncul terus menerus dengan interval waktu tertentu berdasarkan nilai dari variabel respawnTime. Maka kita akan menggunakan class Coroutine dan membuat method IEnumerator dengan nama asteroidsWave. Jadi dengan menggunakan class ini, kita bisa menunda eksekusi method spawnAsteroids dengan selama nilai yang ada didalam variabel respawnTime dalam satuan detik.

Dengan memasukkan si respawnTime kedalam class WaitForSeconds yang ter-inherit dari base class YieldInstruction. dan diikuti dengan memanggil method spawnAsteroids.

// Start is called before the first frame update
void Start() {
    screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
    StartCoroutine(asteroidsWave());
}

Dan yang terakhir, didalam method start yang sudah dibuatkan oleh Unity3D ketika membuat C# Script baru, yaitu method pertama yang dieksekusi oleh sistem saat animasi ini kita play.  Kita akan mengakses method ScreentoWorldPoint yang dimiliki oleh objek Main Camera untuk mengambil ukuran panjang dan tinggi layar serta posisi koordinat z si Main Camera untuk dimasukkan kedalam variabel screenBounds.

Lalu kita akan memulai Coroutine dengan menggunakan method StartCoroutine yang berparameter method asteroidsWave.

Dan membuat C# Script baru lagi dengan nama Asteroids.

public float speed = 1f;
private Rigidbody2D rb;

// Start is called before the first frame update
void Start()
{
    rb = this.GetComponent<Rigidbody2D>();
    rb.velocity = new Vector2(-speed, 0);
}

Jadi begini...

public float speed = 1f;
private Rigidbody2D rb;

Pertama kita membuat variabel yang akan menampung nilai kecepatan berjalan si asteroid dengan tipe data float. Dan membuat variabel untuk mengakses komponen Rigidbody2D dari objek asteroid.

// Start is called before the first frame update
void Start()
{
    rb = this.GetComponent<Rigidbody2D>();
    rb.velocity = new Vector2(-speed, 0);
}

Didalam method Start, pertama kita coba mengambil komponen Rigidbody2D milik si asteroid untuk dimasukkan kedalam variabel rb. Dan selanjutnya memasukkan nilai baru kedalam properti velocity pada RigidBody2D untuk mengatur arah dan kecepatan berjalan dari objek tersebut.

Dengan menggunakan class Vector2 yang merepresentasikan koordinat dari si objek. Dan mengisi properti x nya dengan nilai negatif dari variabel speed supaya bisa start berjalan secara horizontal dari sebelah kanan ke kiri. Dan memberikan nilai 0 kepada properti y supaya objek asteroid tidak bergerak secara vertikal.

Kemudian pasang script Asteroids pada objek asteroids.

Lalu buat folder baru dengan nama Prefabs dan drag objek asteroids kedalam folder tersebut untuk menjadikannya sebagai Prefab. Dan hapus asteroids yang ada di Scene Hierarchy.

Pasang juga script SpawnAsteroids pada objek GameManager. Dan drag Prefab asteroids ke properti Asteroids Prefab serta set Screen Bounds menjadi x = 1366 dan y = 768.

Hasilnya sudah jadi, tapi sebenarnya ada satu masalah yang sangat krusial ketika animasi ini sedang di-play. Yaitu jumlah asteroid yang semakin lama akan menjadi semakin banyak akan membebani memori yang ada di komputer kita.

Kita akan mengakalinya dengan membuat objek baru yang kita beri nama endline. Lalu kita posisikan untuk berada di sebelah kiri layar karena asteroid akan berjalan dari kanan ke kiri. Logikanya adalah objek asteroid akan hancur ketika menyentuh si objek endline ini.

Caranya adalah setelah digeser ke bagian kiri layar, kemudian tambahkan properti Box Collider 2D. Centang properti Is Trigger dan set y size nya menjadi 10. Nanti hasilnya akan seperti ini.

Dan tambahkan C# script baru dengan nama BatasAkhir. isinya kurang lebih seperti ini.

private void OnTriggerEnter2D(Collider2D other) {
    Destroy(other.gameObject);
}

Jadi script ini mendeteksi apabila adaCollider 2D objek lain yang bersentuhan dengan Collider 2D yang dimiliki oleh si endline, maka objek lain tersebut akan di-destroy atau dihancurkan.

Dan pasang script tersebut ke objek endline. Ini hasilnya, objek asteroid terhapus setelah menyentuh objek endline.

Yaps, selesai. coba di-play dan bisa dilihat hasilnya di tab game. Gitu sih penjelasannya. Kalo mau tau lebih detail tentang projeknya bisa main ke online repository-nya disini.

Thanks for stopping by! Semoga harimu menyenangkan!