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
.
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 classInput
, sehingga bisa dipanggil langsung tanpa perlunya instansi dari class tersebut. Informasi lebih lanjut mengenai classInput
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
- Buka scene
Game
yang sebelumnya sudah dibuat. -
Hapus component
Random Start
danUp Movement
yang ada di game objectPlayer
. - Tambahkan component
Movement Input
pada game objectPlayer
. -
Klik tombol
Play
untuk melihat hasilnya.Pada tahap ini, dengan menekan tombol left, right, down, maupun up akan mengakibatkan objek bergerak sesuai dengan arah dari tombol tersebut. Hal ini bisa terjadi karena di setiap frame, component
Movement Input
akan melakukan translasi dari game object sesuai dengan axis dari input yang diberikan oleh pemain.
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.
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
- Buka scene
Game
yang sebelumnya sudah dibuat. - Pada game object
Player
, tambahkan componentRotation Input
. -
Klik tombol
Play
untuk melihat hasilnya.Pada tahap ini, objek akan selalu bergerak berputar menghadap ke posisi mouse. Hal ini sesuai dengan perhitungan atan2 pada component
Rotation Input
yang digunakan untuk mendapat sudut dari perputaran sehingga seolah-olah objek akan selalu menghadap ke arah posisi mouse.
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
- Buka scene
Game
yang sebelumnya sudah dibuat. -
Hapus component
Mesh Filter
,Mesh Renderer
, danBox Collider
.Ketiga component tersebut digunakan untuk menampilkan dan mengatur bounding box dari model 3D. Karena kita akan menggunakan sprite yang basisnya 2D, maka ketiga component tersebut tidak akan digunakan.
-
Pada game object
Player
, tambahkan componentSprite Renderer
dan pada input fieldSprite
tambahkan spritePlayer_1
.Pastikan anda sudah mereset
Scale
dari componentTransform
menjadi1
,1
,1
agar sprite yang ditampilkan memiliki ukuran yang sesuai -
Klik tombol
Play
untuk melihat hasilnya.Pada tahap ini, objek akan berfungsi sama seperti sebelumnya, hanya saja dengan tampilan yang lebih menarik karena alih-alih menggunakan model 3D yang tampak seperti persegi polos, disini kita menggunakan grafik 2D yang lebih sesuai denga game yang akan kita buat.
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).
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
.
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
-
Sprite Rotation
merupakan component yang berfungsi mengubah tampilan sprite dari game object sesuai dengan nilai rotasi yang diberikan.Sebagai catatan, untuk mempersingkat waktu, component
Sprite Rotation
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. - Buka scene
Game
dan pada game objectPlayer
, tambahkan componentSprite Rotation
. -
Pada Insepctor Window Atur
Size
dariSprites
sebanyak8
dan isi keseluruhan element dengan spritePlayer
dariPlayer_0
sampaiPlayer_7
serta aturStart Direction
menjadi-45
.Untuk mempermudah, setiap sprite bisa di drag and drop secara langsung dari folder
Sprites
ke componentSprite Rotation
. -
Untuk percobaan kali ini, kita akan men-_disable_ sementara component
Rotation Input
dengan cara meng-_uncheck_ tombol disebelah nama component. -
Klik tombol
Play
untuk melihat hasilnya.Pada tahap ini, mengubah nilai
Rotation
pada Inspector Window akan secara otomatis mengubah tampilan dari sprite sesuai dengan indeks dari sprite yang sebelumnya kita tambahkan padaSprites
.
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 classMonoBehavior
(parent class dari classRotationInput
). Method ini memiliki kegunaan untuk mengambil referensi class dari component yang ada pada suatu game object. Informasi lebih lanjut dari methodGetComponent<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.