Genre
Ketika kita mengaktifkan fungsi pencarian game di sebuah aplikasi Store, akan muncul
beberapa genre game yang bisa kita nikmati.
Genre Game berbeda-beda berdasarkan cara bermain, tujuan, dan seni di dalamnya, antara
lain:
Pengenalan Academy
Melalui Dicoding Academy ini, peserta akan dikenalkan pada berbagai materi, mulai dari hal
sederhana seperti proses instalasi peranti lunak (software) hingga membuat proyek game
Pukul Bola. Tujuannya, agar peserta siap untuk membuat dan meluncurkan produk game-nya
sendiri.
Unity dapat digunakan untuk membuat game berbasis 3D atau berbasis 2D sehingga
memungkinkan developer untuk berkreasi membuat berbagai jenis game.
OS:
GPU:
Hardware:
Praktik: Unduh Unity
Dalam pembelajaran ini kita menggunakan Unity 2018 dengan menginstall versi 2018 atau
yang terbaru secara online atau offline.
Unity menawarkan 3 pilihan yaitu Unity Personal (Free), Unity Plus, dan Unity Pro atau
kunjungi: https://store.unity.com/
Praktik: Install Unity
1. Buka file yang telah diunduh, kemudian klik Next untuk melanjutkan Instalasi Unity.
2. Kemudian centang kotak Agreement untuk menyetujui ketentuan-ketentuan dari Unity.
Lalu, klik Next untuk melanjutkan instalasi.
Unity 2018, sebuah Unity Editor yang di dalamnya terdapat Monodevelop untuk membuat
sebuah game.
Documentation, berisikan Unity user manual dan referensi Scripting API yang dapat
dikunjungi secara offline.
Standard Assets, terdapat resources baik itu asset atau script untuk memudahkan
developer membangun sebuah game di Unity.
Example Project, sebuah contoh project game yang menggunakan standard asset yang
disediakan oleh Unity.
Build Support, salah satu kelengkapan membuat game dengan mentargetkan platform
tertentu.
4. Setelah itu, tentukan lokasi download dan lokasi install. Jika ingin menyimpan installer
yang telah diunduh, Anda dapat pilih Download to. Kemudian jika ingin memiliki
beberapa versi Unity, Anda dapat menulis misal C:\Program Files\Unity2018.
Klik Next untuk melanjutkan instalasi.
5. Tunggu hingga proses instalasi selesai. Klik Next untuk menyelesaikan.
Praktik: Membuka Unity Pertama kali
Pastikan bahwa ketika pertama kali membuka Unity, komputer anda terkoneksi dengan
Internet, dan ikuti langkah-langkah berikut:
1. Login ke Unity Account. Jika Anda tidak memiliki Unity Account Anda dapat
membuat account baru dengan klik Create one, atau login dengan Google
Account atau Facebook Account.
5. Konfigurasi Unity sudah selesai dan Unity Anda telah siap digunakan. Klik Start Using
Unity untuk membuka Unity.
Hierarchy Window
Hierarchy window digunakan untuk melihat daftar GameObject apa saja yang ada di dalam
scene. Setiap obyek yang ada di scene pasti masuk di Hierarchy.
Scene Window
Scenes Window digunakan untuk melihat secara keseluruhan obyek yang digunakan di
Game. Scenes Window juga dapat mengedit obyek, baik itu dalam posisi, rotasi maupun
skala.
Game View
Game View digunakan untuk melihat hasil akhir dari Game yang nantinya akan ditampilan
ke hadapan user.
Inspector Window
Inspector window digunakan untuk meng-edit semua properties pada obyek yang aktif.
Project Window
Project window digunakan untuk menampilkan daftar aset yang dapat digunakan dalam
proyek Anda. Ketika menambahkan asset baru, maka akan muncul di Project Window.
Console Window
Digunakan untuk mengetahui log-log dalam script dan informasi error serta peringatan yang
ada di script.
Pertanyaan:
Dari Gambar ini:
Pernyataan:
A. Tool yang digunakan untuk mengatur nilai Transfrom (Posisi, Rotasi dan Skala)
D. Tampilan interaktif untuk Menyusun posisi, rotasi dan skala seluruh GameObject.
Jawaban Anda
1G, 2D, 3F, 4A
KIRIM JAWABAN
Basic Scripting
Kita akan membuat C# Script sederhana dengan menampilkan sebuah Log di jendela
Console.
Kita bersiap membuat sebuah proyek baru yang akan digunakan di pembelajaran ini.
Mode : 2D
Klik Create project
Praktik: Membuat Script
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassLatihan1:MonoBehaviour{
6.
7. // Use this for initialization
8. voidStart(){
9.
10. }
11.
12. // Update is called once per frame
13. voidUpdate(){
14.
15. }
16. }
Secara default, pada script yang baru dibuat akan ditampilkan 2 buah prosedur, yaitu:
Start()
Prosedur ini akan dipanggil satu kali di awal, pada saat script pertama kali di-enable.
Prosedur ini sesuai untuk inisialisasi.
Update()
Prosedur ini dipanggil pada setiap frame, apabila script di-enable. Prosedur ini sesuai
untuk bagian script yang dieksekusi berulang-ulang.
Untuk daftar prosedur dan fungsi lengkap yang ada pada kelas MonoBehaviour,
silakan lihat pada link: https://docs.unity3d.com/ScriptReference/MonoBehaviour.html.
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassLatihan1:MonoBehaviour
6. {
7.
8. // Use this for initialization
9. voidStart()
10. {
11. Debug.Log("Hello Dicoding!");
12. }
13.
14. // Update is called once per frame
15. voidUpdate()
16. {
17.
18. }
19. }
20.
Pembahasan Code:
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
Library di atas merupakan Library yang digunakan dalam perintah dalam script.
Seperti penggunaan variable GameObject, Monobehavior, dll.
1. publicclassLatihan1
Nama kelas dari sebuah script. Nama Kelas harus sama dengan nama file C# Script
di folder Assets.
1. voidStart()
Fungsi di atas hanya dijalankan satu kali dan diawal saat program dijalankan
1. Debug.Log("Hello Dicoding!");
1. voidUpdate()
Dijalankan berulang-ulang setelah menjalankan function Start().
Praktik: Menjalankan Script
3. Jika di klik Info tersebut maka akan muncul Jendela Console. Sebagai berikut:
Jika Anda klik salah satu list yang terdapat di Console, akan muncul info detail dari informasi
nama berkas (file) script sampai baris kode tersebut. Anda dapat menghilangkan info tersebut
dengan klik tombol Clear.
5.Anda dapat simpan dengan klik menu File > Save Senes atau tekan Ctrl+S. Kemudian beri
nama Main.unity
Quiz Mini:
Menampilkan Nama Anda di Jendela Console, misalkan “Saya <Nama Kamu> adalah
Game Developer”
MonoBehaviour
MonoBehaviour adalah class dasar dari setiap script Unity yang dibuat. Ketika Anda
menggunakan C#, MonoBehaviour secara otomatis (default) akan tercipta.
Berikut ini kotak centang untuk mengaktifkan atau menonaktifkan MonoBehaviour (script)
pada Unity Editor. Letaknya ada pada tab Inspector.
1. Awake() dan Start()
2. Update(), FixedUpdate(), dan LateUpdate()
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassLatihanAwake:MonoBehaviour{
6. voidAwake(){
7. Debug.Log("Awake Dipanggil");
8. }
9. }
Pembahasan kode:
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
3 baris kode di atas adalah Library bawaan saat script dibuat. Kita dapat memberi Library
tambahan seperti scene, UI dan lainnya.
1. public class LatihanAwake:MonoBehaviour
Nama kelas dari script. Nama kelas harus sama dengan berkas (file) script yang dibuat.
1. void Awake()
1. Debug.Log("Awake Dipanggil");
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. public class LatihanStart:MonoBehaviour{
6. void Start(){
7. Debug.Log("Start Dipanggil");
8. }
9. }
Pembahasan kode:
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
3 baris kode di atas adalah Library bawaan saat script dibuat. Kita dapat memberi Library
tambahan seperti scene, UI dan lainnya.
1. public class LatihanStart:MonoBehaviour
Nama kelas dari script. Nama kelas harus sama dengan berkas script yang dibuat.
1. void Start()
1. Debug.Log("Start Dipanggil");
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. public class Latihan1:MonoBehaviour{
6. //fungsi Awake
7. void Awake(){
8. Debug.Log("Awake dipanggil");
9. }
10.
11. //fungsi Start
12. void Start(){
13. Debug.Log("Start dipanggil");
14. }
15. }
Update
Update akan aktif jika MonoBehaviour diaktifkan. Update akan terpanggil sesudah Start
dipanggil. Update adalah fungsi yang paling sering digunakan untuk
menerapkan script game. Namun, tidak semua MonoBehaviour membutuhkan script Update.
Biasanya kita membuat method baru untuk mendeklarasikan sebuah fungsi.
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. public class LatihanUpdate:MonoBehaviour{
6. void Update(){
7. Debug.Log("Waktu untuk Update :"+Time.deltaTime);
8. }
9. }
Pembahasan kode:
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
3 baris kode di atas adalah Library bawaan saat script dibuat. Kita dapat memberi Library
tambahan seperti scene, UI dan lainnya.
1. public class LatihanUpdate:MonoBehaviour
Nama kelas dari script. Nama kelas harus sama dengan berkas script yang dibuat.
1. void Update()
Dijalankan saat fungsi Update() dijalankan dan akan menampilkan waktu yang sama.
FixedUpdate
FixedUpdate biasanya digunakan sebagai gantinya Update ketika bertemu dengan
Rigidbody. Misalnya saat menambahkan physic ke benda.
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. public class LatihanFixedUpdate:MonoBehaviour{
6. void FixedUpdate(){
7. Debug.Log("Waktu untuk FixedUpdate :"+Time.deltaTime);
8. }
9. }
Pembahasan kode:
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
3 baris kode di atas adalah Library bawaan saat script dibuat. Kita dapat memberi Library
tambahan seperti scene, UI dan lainnya.
1. public class LatihanFixedUpdate:MonoBehaviour
Nama kelas dari script. Nama kelas harus sama dengan berkas script yang dibuat.
1. voidFixedUpdate()
LateUpdate
LateUpdate dipanggil setelah semua fungsi Update dipanggil. Ia berguna untuk memberi log
console eksekusi script. Contohnya, Camera Follow harus selalu diimplementasikan di
LateUpdate karena melacak objek yang mungkin telah bergerak di dalam Update.
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. public class LatihanLateUpdate:MonoBehaviour{
6. void LateUpdate(){
7. Debug.Log("Waktu untuk LateUpdate :"+Time.deltaTime);
8. }
9. }
Pembahasan kode:
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
3 baris kode di atas adalah Library bawaan saat script dibuat. Kita dapat memberi Library
tambahan seperti scene, UI dan lainnya.
1. public class LatihanLateUpdate:MonoBehaviour
Nama kelas dari script. Nama kelas harus sama dengan berkas script yang dibuat.
1. void LateUpdate()
Fungsi ini akan dipanggil saat script diaktifkan dan dijalankan setelah Update() dan
FixedUpdate().
Dijalankan saat fungsi LateUpdate() dijalankan dan akan menampilkan waktu berbeda.
Berikut ini contoh penerapan ketiga fungsi Update, FixedUpdate dan LateUpdate.
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. public class Latihan1:MonoBehaviour{
6. void FixedUpdate(){
7. Debug.Log("Waktu untuk FixedUpdate :"+Time.deltaTime);
8. }
9.
10. void Update(){
11. Debug.Log("Waktu untuk Update :"+Time.deltaTime);
12. }
13.
14. void LateUpdate(){
15. Debug.Log("Waktu untuk LateUpdate :"+Time.deltaTime);
16. }
17. }
Jika Anda ingin menggunakan Editor yang lebih terdepan, Anda dapat menggunakan Visual
Studio. Tetapi jika ingin yang lebih ringan, Anda dapat menggunakan Notepad++ .
Pemilihan itu tergantung kenyamanan Anda dalam menulis kode dan spesifikasi komputer
Anda.
Untuk mengganti editor script, Anda dapat lakukan langkah-langkah sebagai berikut:
1. Klik Menu Edit > Preferences...
2. Pada Jendela Unity Preferences, buka tab External Tools kemudian pada External
Script Editor. Anda dapat memilih editor yang Anda inginkan dan dapat pula menambahkan
Editor baru dengan Klik Browse.
3. Jika Anda mengganti Editor, disarankan untuk me-restart Unity Anda, sehingga tampilan
sebagai berikut:
MonoDevelop
Variable
Sebuah variable dapat menyimpan satu dari dua tipe nilai, yaitu value type dan references
type.
Values Type adalah dasar dari tipe data primitive seperti char, int, dan float, serta tipe user-
defined yang dideklarasikan dengan struct.
Reference Type adalah kumpulan class atau data kompleks yang dibangun dari tipe data
primitive.
Modifier Access
Modifier Access merupakan hak akses user untuk memanggil sebuah variable dari sebuah
kelas.
Public
Variable yang dapat dipanggil/diakses dari kelas lain
Misal:
Ada beberapa cara deklarasi variable yang sering digunakan dalam membuat Game. Cara
tersebut dikelompokkan sebagai berikut:
Global Variable
Variable yang dapat digunakan atau dipanggil oleh semua fungsi atau method
Misal:
1. publicclassContoh:MonoBehaviour{
2. string nama ="Dico";// Global Variable
3.
4. voidStart(){
5. Debug.Log("My Name: "+nama);// Kamu dapat panggil disini
6. }
7.
8. voidUpdate(){
9. Debug.Log("My Name: "+nama);// Kamu dapat panggil disini
10. }
11. }
Local Variable
Variable yang hanya dipanggil pada method atau fungsi yang dimana variable tersebut di
deklarasikan.
Misal:
1. publicclassContoh:MonoBehaviour{
2.
3. voidStart(){
4. string nama ="Dico";// Local Variable
5. Debug.Log("My Name: "+nama);// Kamu dapat panggil disini
6. }
7.
8. voidUpdate(){
9. // Kamu tidak dapat panggil disini
10. }
11. }
Constant Variable
Variable yang memiliki nilai tetap dan tidak dapat diubah.
Misal:
1. publicclassContoh:MonoBehaviour{
2. conststring ID ="1234";// Constant Variable
3. }
Static Variable
Variable yang dapat langsung dipanggil oleh kelas lain tanpa harus membuat object dari kelas
itu sendiri.
Misal:
Kelas yang terdapat variable static
1. publicclassData{
2. publicstaticstring ID ="1234";// Static Variable
3. }
4. publicclassContoh:MonoBehaviour{
5.
6. voidStart(){
7. Debug.Log("ID: "+Data.ID);// Kamu dapat panggil disini
8. }
9. }
Penulisan nama variable sebenarnya bebas, tetapi untuk membedakan penulisan yang lain
(kelas dan fungsi) maka membutuhkan penulisan khusus:
Jika lebih dari 2 kata, maka Kata kedua diawali huruf besar.
Misal: playerController, enemyZombie.
Tetapi hal diatas tidak berlaku pada variable Konstanta. Untuk Variable Konstanta memiliki
aturan sebagai berikut:
Semua huruf pada kata terdiri dari huruf besar
Misal: TOKEN
Jika lebih dari 2 kata, maka dipisahkan dengan garis bawah (Underscore)
Misal: TOKEN_ADS
1. Buat C# Script baru dengan klik kanan pada jendela Project > Create > C# Script >
Langsung beri nama Latihan2
2. Drag Script Latihan2.cs ke GameObject Main Camera di Jendela Hierarchy
Praktik: Variable unity
1. Buka Script Latihan2.cs
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassLatihan2:MonoBehaviour
6. {
7.
8. int nilaiA =5;
9. int nilaiB =9;
10.
11. // Use this for initialization
12. voidStart()
13. {
14. int totall = nilaiA + nilaiB;
15. Debug.Log("Total "+ totall);
16. }
17.
18. // Update is called once per frame
19. voidUpdate()
20. {
21.
22. }
23. }
Kita dapat mengubah nilai variable NilaiA dan NilaiB lewat jendela Inspector dan tanpa
harus mengubah nilai variable tersebut di script. Caranya kita menggunakan variable public
untuk memunculkan field di Inspector. Detailnya sebagai berikut:
1. Buka script Latihan2.cs
Menjadi
3. publicint nilaiA;
4. publicint nilaiB;
Kemudian simpan perubahan dengan tekan Ctrl+S
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassLatihan2:MonoBehaviour
6. {
7.
8. publicint nilaiA;
9. publicint nilaiB;
10.
11. // Use this for initialization
12. voidStart()
13. {
14. int totall = nilaiA + nilaiB;
15. Debug.Log("Total "+ totall);
16. }
17.
18. // Update is called once per frame
19. voidUpdate()
20. {
21.
22. }
23. }
Praktik: Attribute Variable
1. Buka Script Latihan2.cs
1. [Range(1,5)]
2. publicint nilaiC;
Ubah code yang terdapat di dalam function Start()
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassLatihan2:MonoBehaviour
6. {
7.
8. publicint nilaiA;
9. publicint nilaiB;
10. [Range(1,5)]
11. publicint nilaiC;
12.
13. // Use this for initialization
14. voidStart()
15. {
16. int totall =(nilaiA + nilaiB)* nilaiC;
17. Debug.Log("Total "+ totall);
18. }
19.
20. // Update is called once per frame
21. voidUpdate()
22. {
23.
24. }
25. }
Pada field NilaiC, hanya dapat diisi dari nilai 1 sampai nilai 5. Anda dapat mengganti nilai
dengan menggeserkan slider atau langsung memasukkan nilai kedalam field.
Jika dijalankan sebagai berikut:
Anda dapat simpan yang telah Anda kerjakan di atas dengan klik menu File > Save
Scenes atau tekan Ctrl+S.
Function
Di dalam pemrograman, function juga digunakan untuk memudahkan kita untuk memahami
sekumpulan kode. Apabila menggunakan function, kode akan lebih sederhana dan rapi jika
diimplementasikan dengan baik.
1. Tambahkan();
Jika Nama fungsi lebih dari 2 kata maka kata kedua menggunakan huruf besar
Misal:
1. SamaDengan();
Untuk memudahkan pembelajaran, buat script baru dengan nama Latihan3.cs. Langkah-
langkahnya sebagai berikut:
1. Buat C# Script baru dengan klik kanan pada jendela Project > Create > C# Script >
Langsung beri nama Latihan3.
Dengan ini, Main Camera hanya menjalankan script Latihan 3, namun tidak Latihan 2.
Praktik: Function
1. Buka Script Latihan3.cs
1. intJumlah(int a,int b)
2. {
3. return a + b;
4. }
1. int c =Jumlah(60,40);
2. Debug.Log("Hasil Jumlah a dan b adalah "+ c);
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassLatihan3:MonoBehaviour
6. {
7.
8. // Use this for initialization
9. voidStart()
10. {
11. int c =Jumlah(60,40);
12. Debug.Log("Hasil Jumlah a dan b adalah "+ c);
13. }
14.
15. // Update is called once per frame
16. voidUpdate()
17. {
18.
19. }
20.
21. intJumlah(int a,int b)
22. {
23. return a + b;
24. }
25. }
1. Ketik “/” sebanyak 3 kali diatas fungsi Jumlah() kemudian akan muncul template comment
seperti di bawah ini:
Fitur di atas hanya dapat dilakukan di Editor MonoDevelop dan Visual Studio.
2. Pada Summary, tambahkan informasi tentang kegunaan fungsi tersebut. Kemudian pada
parameter, tambahkan informasi tentang masing-masing parameter. Sehingga hasinya sebagai
berikut:
3. Coba lakukan dengan memanggil ulang function tersebut di dalam fungsi Start(), maka
informasi yang telah dimasukkan akan muncul.
Comment ini akan sangat membantu jika kode yang kita tulis kompleks yang karenanya kita
biasa memerlukan catatan di fungsi tersebut.
Setiap Object dapat memanggil Property dan Method yang memiliki access modifier public
yang terdapat di dalam suatu Class.
Berikutnya adalah contoh penerapan Class dan Object pada game, tepatnya pada class
Karakter yang nantinya akan digunakan sebagai Object di Player. Perhatikan bagan di bawah
ini:
Sebuah Class Karakter memiliki Property seperti Name, Health, Damage. Class tersebut juga
memiliki Method seperti MoveLeft(), MoveRight(). Jump() dan Attact(). Pada Object Player
yang merupakan presentasi dari Class Karakter, Anda dapat menggunakan dan mengubah
nilai yang terdapat di Properties dan dapat juga memanggil Methods yang terdapat di
Karakter.
Kemudian kita akan membuat sebuah class dengan nama Karakter di dalam Folder Latihan4
1. Buatlah Folder dengan nama Latihan4 agar script di submodul ini tertata rapi.
Supaya script di submodul ini lebih rapi, buat dan kumpulkan scripts ke dalam 1 Folder
3. Buka script Karakter.cs dan ubah seluruh isi di dalam kelas Karakter seperti di bawah ini.
1. usingUnityEngine;
2. publicclassKarakter{
3.
4.
5. }
Setiap script C#, pada bagian atas selalu diawali dengan nama Class. Penggunaan access
control class tersebut menggunakan public class supaya ia dapat dipanggil di class lain untuk
dijadikan sebagai object. Selanjutnya, kita menghilangkan turunan dari MonoBehavior.
Kenapa? Karena pada Class ini tidak membutuhkan fungsi yang terdapat di dalam
MonoBehavior.
1. privatestring name;
2. privateint health;
3. privateint damage;
4.
5. publicstringName
6. {
7. get
8. {
9. return name;
10. }
11. set
12. {
13. name =value;
14. }
15. }
16.
17. publicintHealth
18. {
19. get
20. {
21. return health;
22. }
23. set
24. {
25. health =value;
26. }
27. }
28.
29. publicintDamage
30. {
31. get
32. {
33. return damage;
34. }
35. set
36. {
37. damage =value;
38. }
39. }
1. usingUnityEngine;
2. publicclassKarakter
3. {
4. privatestring name;
5. privateint health;
6. privateint damage;
7.
8. publicstringName
9. {
10. get
11. {
12. return name;
13. }
14. set
15. {
16. name =value;
17. }
18. }
19.
20. publicintHealth
21. {
22. get
23. {
24. return health;
25. }
26. set
27. {
28. health =value;
29. }
30. }
31.
32. publicintDamage
33. {
34. get
35. {
36. return damage;
37. }
38. set
39. {
40. damage =value;
41. }
42. }
43.
44. publicvoidMoveLeft()
45. {
46. Debug.Log("Gerak ke kiri");
47. }
48. publicvoidMoveRight()
49. {
50. Debug.Log("Gerak ke kekanan");
51. }
52. publicvoidJump()
53. {
54. Debug.Log("Loncat");
55. }
56. publicvoidAttack()
57. {
58. Debug.Log("Serang");
59. }
60. }
Ayo kita membuat kelas baru yang nantinya akan memanggil class Karakter sebagai object.
1. Karakter player1;
Menginisialisasi player1 didalam function Start()
1. player1 =newKarakter();
2. player1.Name="Dico";
3. player1.Health=100;
4. player1.Damage=30;
5. //Menampilkan hasil dari inisialisasi attribute
6. Debug.Log("Name: "+player1.Name+", Health: "+player1.Health+", Damage:
"+player1.Damage);
7. //Memanggil method dari salah satu method di class Karakter.
8. player1.Jump();
Simpan perubahan script dengan tekan Ctrl+S
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassLatihan4:MonoBehaviour
6. {
7. Karakter player1;
8. // Use this for initialization
9. voidStart()
10. {
11. player1 =newKarakter();
12. player1.Name="Dico";
13. player1.Health=100;
14. player1.Damage=30;
15. //Menampilkan hasil dari inisialisasi attribute
16. Debug.Log("Name: "+ player1.Name+", Health: "+ player1.Health+", Damage: "+
player1.Damage);
17. //Memanggil method dari salah satu method di class Karakter.
18. player1.Jump();
19. }
20.
21. // Update is called once per frame
22. voidUpdate()
23. {
24.
25. }
26. }
Jendela Console menampilkan log informasi dari Attribute function dan dari function jump.
Inheritance
Inheritance atau warisan adalah konsep Pemrograman Berorientasi Objek (OOP) yang
digunakan untuk mengakses dan menggunakan kembali sifat atau metode satu kelas dari
kelas lainnya.
Di dalam inheritance, kelas dasarnya dikenal sebagai Base Class (kelas dasar). Sementara
kelas yang mewarisi dari base dikenal sebagai Derived Class (kelas turunan).
Ketika membuat kelas baru di Unity, maka secara otomatis kelas tersebut merupakan turunan
dari MonoBehaviour sebagai default-nya. Di dalam kelas turunan ini kita bisa mengakses
banyak fungsi seperti Update(), Start(), dan fungsi lain yang dimiliki oleh Class
Monobehaviour.
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassKosongan:MonoBehaviour
6. {
7. // Use this for initialization
8. voidStart()
9. {
10.
11. }
12.
13. // Update is called once per frame
14. voidUpdate()
15. {
16.
17. }
18. }
Kemudian pada Base Class (Kelas Dasar) dapat diturunkan kebeberapa kelas turunan. Kelas
turunan tersebut juga dapat diturunkan kembali ke kelas turunan yang lain, seperti yang
ditampilkan pada bagan di bawah ini:
Kelas B memiliki warisan dari Kelas A, sedangkan Kelas D memiliki warisan dari Kelas C
dan Kelas A.
Berikut ini adalah contoh turunan pada variable dari base kelas (kelas dasar) ke kelas yang
lain
Kemudian ada 3 access modifier untuk menentukan apa saja function yang dapat diturunkan
atau tidak dengan sebagai berikut:
1. Public, merupakan feature pada method, property atau variable yang dapat diturunkan kepada
kelas yang diwariskan dan dapat diakses juga oleh kelas yang bukan turunannya.
2. Protected, murupakan feature pada method, property atau variable yang dapat diturunkan
kepada kelas yang diwariskan tetapi tidak dapat diakses oleh kelas yang bukan turunannya.
3. Private, murupakan feature pada method, property atau variable yang tidak dapat diturunkan
kepada kelas yang diwariskan tetapi tidak dapat diakses oleh kelas yang bukan turunannya.
Praktik: Membuat Kelas Base
3. Buka script Manusia.cs dengan klik 2 kali dan tambahkan kode di dalam Kelas Manusia di
bawah ini:
1. publicvoidMakan(){
2. Debug.Log("Perlu Makan");
3. }
4. publicvoidTidur(){
5. Debug.Log("Perlu Tidur");
6. }
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassManusia:MonoBehaviour
6. {
7. publicvoidMakan()
8. {
9. Debug.Log("Perlu Makan");
10. }
11. publicvoidTidur()
12. {
13. Debug.Log("Perlu Tidur");
14. }
15. }
1. publicclassPrajurit:Manusia
Tambahkan method ini di dalam kelas Prajurit
1. voidMenyerang(){
2. Debug.Log("Menyerang");
3. }
Tambahkan kode ini di dalam method Start()
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassPrajurit:Manusia
6. {
7. voidStart()
8. {
9. Debug.Log("Seorang Prajurit dapat : ");
10. Makan();
11. Tidur();
12. Menyerang();
13. }
14.
15. voidUpdate()
16. {
17.
18. }
19.
20. voidMenyerang()
21. {
22. Debug.Log("Menyerang");
23. }
24. }
Array
Jika Anda terbiasa menggunakan bahasa Java, mungkin akan sedikit bingung dengan
penulisan Array di C#. Perbedaannya Anda dapat pelajari di pembahasan ini.
Array digunakan untuk menyimpan tipe data sejenis yang dikelompokkan sebagai satu
kesatuan. Seperti contoh di bawah ini:
Dengan menyimpan tipe data integer dengan 5 data yaitu 50, 20, 30, 10, dan 40. Data tersebut
dapat diakses oleh nomor index misal untuk mendapatkan nilai data 10 pada index 3 maka
dapat ditulis myArray[3]. Sedangkan beberapa latihan tentang array seperti berikut:
Multi-Dimensional Arrays
Berikut ini contoh array dengan 2 Dimensi. Untuk array 2 dimensi untuk mendapatkan sebuah
nilai, maka diperlukan 2 buah nilai misal Baris ke 4 dan Kolom ke 3.
Misal:
https://docs.unity3d.com/ScriptReference/Array.html
Supaya script Latihan6.cs dijalankan oleh Main Camera ketika menjalankan Play Mode.
3. Klik GameObject Main Camera di Hierarchy, Kemudian lihat Jendela Inspector. Lalu
hilangkan centang pada script Prajurit.cs
Dengan ini, Main Camera akan menjalankan script Latihan 6, bukan script Prajurit
1. int[] intArray;
menjadi
1. publicint[] intArray;
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4.
5. publicclassLatihan6:MonoBehaviour
6. {
7.
8. publicint[] intArray;// Deklarasi Array
9.
10. // Use this for initialization
11. voidStart()
12. {
13. Debug.Log("Menampilkan Seluruh Array");
14. foreach(int a in intArray)
15. {
16. Debug.Log(a);
17. }
18. Debug.Log("Nilai Index ke 2 adalah "+ intArray[2]);
19. }
20.
21. // Update is called once per frame
22. voidUpdate()
23. {
24.
25. }
26. }
2. Kembali ke Unity dan Klik GameObject Main Camera. Kemudian pada Inspector. klik
icon panah pada field IntArray
3. Masukkkan Size 5 dan masukkan ke-5 angka tersebut
Jawaban Anda
3, 4, 5
1, 4, 5
2, 4, 5
1, 2, 5
1, 3, 4
1. Buka Unity
2. Klik New
4. Centang/pilih 2D
6. Untuk tutorial ini, pilih OFF di sebelah tulisan “Enable Unity Analytics”
Setalah Anda membuat file project, selanjutnya Anda akan mempelajari beberapa modul
sebagai berikut:
Memasukkan Assets
Membuat Area Game
Membuat Paddle (Pemukul)
Membuat Bola
Menambahkan Audio
Membuat Score
Membuat Halaman Game Over dan Halaman Menu
Selanjutnya akan Membahas tentang Memasukkan Aset
Memasukkan Aset
Menyiapkan Assets
Lingkaran
Nama : Lingkaran.png
Ukuran : 64x64 pixel
Warna : Putih
Keterangan : Lingkaran penuh dengan warna putih
Persegi
Nama : Persegi.png
Ukuran : 64x64 pixel
Warna : Putih
Keterangan : Blok penuh dengan warna putihGambar ini akan digunakan sebagai Paddle
dan WallAnda dapat membuat sendiri, Tool free yang dapat Anda gunakan:
https://www.getpaint.net/
Anda dapat Unduh kedua gambar disiniUnduh Aset Game Pukul Bola
Praktik: Membuat Folder
Supaya penyusunannya rapi maka perlu pengelompokan berdasarkan jenis berkas (file) yang
sama dalam satu folder. Caranya dengan buka panel Project, kemudian klik kanan
pilih Create > Folder. Beri
nama Images.
Anda juga dapat mengganti nama folder dengan klik kali pada nama folder maka tunggu
beberapa saat kemudian muncul edit teks pada nama folder atau Anda juga dapat dengan klik
Folder kemudian tekan F12 pada keyboard.
Gambar-gambar yang telah kita buat/unduh, selanjutnya kita masukkan aset ke proyek.
Langkah-langkahnya sebagai berikut:
1. Masuk kedalam folder Images yang telah dibuat dengan klik 2 kali. Kemudian klik kanan
> Import New Asset…
Setelah membuat Project untuk pertama kali, Pada panel Hierarchy, terdapat sebuah Scene
(Untitled) yang memiliki satu Main Camera.
Scene yang pertama kali dibuat ini belum tersimpan. Untuk menyimpan Scene, ikuti langkah-
langkah berikut:
Membuat Background
Sebelum menyusun sebuah tampilan, sebaiknya tentukan terlebih dahulu resolusi yang
digunakan. Karena target platform adalah Android, maka kita menggunakan resolusi 16:9.
Pengaturan tersebut, dapat Anda lakukan dengan dengan membuka panel Game. Kemudian
Pilih Resolusi 16:9
Anda juga dapat menambahkan resolusi tertentu dengan menekan tombol plus (+).
Kamu dapat melihat komponen-komponen dari sebuah GameObject dengan cara klik pada
GameObject yang ingin dilihat. Lalu lihat pada Inspector. Coba klik dua kali pada Main
Camera, lalu lihat bagian Inspector dari Main Camera. Komponen apa sajakah yang dimiliki
oleh Main Camera?
Default warna latar belakang adalah biru tua. Untuk mengubah warnanya, klik dua kali pada
Background di komponen Camera. Kemudian akan terbuka color picker untuk memilih
warna background yang diinginkan. Di pembelajaran ini kita menggunakan warna hitam
sebagai background. Sehingga hasilnya seperti berikut ini:
Hasilnya sebagai berikut:
Selanjutnya akan Membahas tentang Membuat Area Game
Untuk menyusun Object, Anda dapat menggunakan toolbox yang telah disediakan
Dengan tool tersebut, Anda dapat melakukan menggerakkan, memutar atau mengatur besar
kecil object. Anda juga dapat mengatur nilai pada Komponen Transform di Panel Inspector.
Selanjutnya kita akan membuat Tepi dan Garis Pembatas Tengah sebagai area game.
Langkah pertama kita akan membuat Tepi Atas terlebih dahulu dengan langkah-langkah
sebagai berikut:
TepiBawah
TepiKiri
BatasTengah
Selanjutnya, tambahkan tepi kiri, tepi kanan, dan batas tengah dengan cara yang
sama. Atur ukuran dan posisi tepi kiri, tepi kanan, dan batas tengah. Setelah semua tepi dan
batas ditambahkan, hasilnya sebagai berikut:
Setelah Anda selesai membuat tampilan Area Game, selanjutnya Anda menambahkan
Collider sebagai pembatas area agar bola tidak dapat tembus keluar area. Langkah-
langkahnya sebagai berikut.
1. Klik GameObject TepiAtas yang terdapat di Hierarchy
Di submodul ini kita akan membuat Paddle yang bergerak ke atas dan ke bawah dengan
menekan tombol keyboard.
Selanjutnya kita akan membuat Paddle sebagai player. Langkah-langkahnya sebagai berikut:
4. Karena Paddle merupakan objek yang tidak dapat ditembus oleh objek lain maka
tambahkan Komponen Collision dengan cara Klik Add Component > Physics 2D > Box
Collider 2D
Dalam tutorial ini, kedua paddle akan digerakkan dengan menggunakan keyboard. Pemukul
pemain pertama (sebelah kiri) digerakkan dengan tombol W dan S sementara Pemukul
pemain kedua (sebelah kanan) digerakkan dengan tombol ↑ dan ↓. Lakukan langkah berikut
untuk setting input:
2. Untuk dua varian input terbawah, ikuti setting pada screenshot berikut
Tips: di versi Unity yang terbaru, jika Anda mengedit yang sudah ada misal Vertical maka
akan muncul error.
Dari sini, kita memiliki 2 varian customized input
Vertical 1
Ini akan digunakan untuk menggerakkan Pemukul dari player 1. Pemukul dari player 1 akan
digerakkan ke bawah (negative button) dengan tombol s dan bergerak ke atas (positive button)
dengan tombol w.
Vertical 2
Ini akan digunakan untuk menggerakkan Pemukul dari player 2. Pemukul dari player 2 akan
bergerak ke bawah (negative button) dengan tombol (down) dan bergerak ke atas (positive
button) dengan tombol ↑ (up).
Selanjutnya, kita perlu membuat Script agar Pemukul dapat bergerak sesuai dengan masukan
dari keyboard.
1. Pada Folder Assets, Tambahkan Folder baru. Klik Kanan pada Panel Project, kemudian
pilih Create > Folder lalu beri nama Scripts
2. Di dalam folder Scripts yang telah dibuat, tambahkan script baru dengan
nama PaddleController.cs. (Klik kanan > Create > C# Scripts)
3. Pada script PaddleController.cs, Klik dua kali pada file “ PaddleController.cs” untuk
mulai menambahkan script. Setiap Script pada Unity merupakan turunan dari
kelas MonoBehaviour, sehingga semua fungsi dan prosedur yang ada pada kelas
MonoBehaviour dapat dimanfaatkan pada script.
kecepatan pergerakan Paddle/Pemukul
varian input mana yang mengatur paddle tersebut: Vertical 1 atau Vertical 2
perubahan posisi pada sumbu Y sesuai dengan tombol yang ditekan
using UnityEngine;
public class PaddleController : MonoBehaviour {
public float kecepatan;
public string axis;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float gerak = Input.GetAxis(axis) * kecepatan * Time.deltaTime;
transform.Translate(0, gerak, 0);
}
}
Pembahasan
Dalam screenshot di atas, Kecepatan diisi dengan 7, sementara Axis diisi dengan Vertical1.
Hal ini berarti, kecepatan perpindahan adalah 7 dikali hasil pembacaan keyboard. Sementara
untuk memindahkan pemukul akan digunakan varian input Vertical 1, yaitu w untuk
perpindahan ke atas dan s untuk perpindahan ke bawah. Pada saat di-play, dengan menekan
tombol w dan s, pemukul player 1 akan bergerak sebagai berikut.
Dari gif di atas, Pemukul bergerak secara vertical ketika ditekan tombol w dan s.
Dalam pemrograman, seringkali kita perlu mengatur sesuatu berdasarkan kondisi tertentu.
Misalnya dalam kasus Pemukul, perpindahan posisi Pemukul perlu dibedakan berdasarkan
state dari Pemukul tersebut. Berikut ini logika kondisi yang digunakan dalam pengaturan
posisi Pemukul.
Apabila nilai yang diinputkan melebihi batas atas maka nilai inputan menjadi 0 berarti
GameObject pemukul tidak bergerak
Apabila nilai yang diinputkan kurang dari batas bawah maka nilai inputan menjadi 0 berarti
GameObject pemukul tidak bergerak
Apabila pemukul berada dalam batas bawah dan batas atas maka pemukul bebas untuk
berpindah ke mana pun.
1. Buka script PaddleController.cs dengan klik 2 kali, kemudian tambahkan code di bawah
ini.
using UnityEngine;
public class PaddleController : MonoBehaviour
{
public float batasAtas;
public float batasBawah;
public float kecepatan;
public string axis;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
float gerak = Input.GetAxis (axis) * kecepatan * Time.deltaTime;
float nextPos = transform.position.y + gerak;
if (nextPos > batasAtas) {
gerak = 0;
}
if (nextPos < batasBawah) {
gerak = 0;
}
transform.Translate (0, gerak, 0);
}
}
Memprediksi nilai posisi posisi selanjutnya apakah menewati batas atas atau batas bawah.
Jika melewati maka paddle tidak ada pergerakkan selanjutnya.
2. Untuk mengetahui batasAtas dan batas bawah, Anda dapat lakukan dengan menggeser
paddle ke posisi paling atas. Anda dapat lihat nilai Y pada komponen Transfrom
Kita telah mendapatkan nilai batas atas yaitu sebesar 3.45, sedangkan untuk nilai batas bawah
adalah nilai negatif dari 3.45 yaitu -3.45. Setelah mendapatkan nilai tersebut, jangan lupa
untuk mengembalikan posisi semula pada paddle dengan nilai y sama dengan 0.
3. Kemudian isikan kedua nilai tersebut pada filed Batas Atas dan Batas Bawah.
Sekarang Anda sudah dapat membuat paddle yang dapat bergerak ke atas dan ke bawah tanpa
menembus dinding.
Selanjutnya: Membuat Bola
Membuat Bola
Di submodul ini, kita akan menerapkan 2D Physics ke Bola, antara lain sebagai berikut:
RigidBody 2D, Sebuah komponen yang menerapan hukum fisika pada suatu gameobject 2D.
Collider 2D, sebuah komponen yang menggambarkan bentuk sebuah fisik yang dapat
digunakan untuk mendeteksi benturan dengan benda lain.
Physics Material 2D, digunakan untuk mengatur nilai gesekan atau pantulan terhadap
benturan benda lain.
Pertama, kita membuat objek Bola terlebih dahulu dengan cara sebagai berikut:
1. Buka Inspector pada Bola, Lalu tambahkan komponen RigidBody 2D (Add Component >
Physics 2D > Rigidbody 2D). Kemudian atur nilai Linear Drag, Angular Drag, Gravity
Scale menjadi 0. Jangan lupa untuk centang Freeze Rotation Z.
2. Tambahkan komponen Circle Collider 2D (Add Component > Physics 2D > Circle
Collider 2D).
3.Buat folder baru dengan nama Physics. Kemudian buat Physics Material 2D dengan klik
kanan pada panel Project > Create > Physics Material 2D dan beri nama PhysicsBola.
4. Klik PhysicsBola pada panel Project. Kemudian pada Inspector, atur nilai sebagai berikut.
Friction menjadi 0 dan Bounciness menjadi 1.
Kali ini, kita akan mencoba menggerakkan Bola dengan menggunakan Force (tekanan).
Seperti dalam hukum Fisika, kecepatan dan arah pergerakan Bola ditentukan oleh dua hal:
Arah dan besaran Force (tekanan)
Massa bola
Force dalam Unity ditambahkan pada Rigidbody 2D. Dalam tutorial ini, kita mencoba
menambahkan Force sebagai pergerakan Bola pertama kali. Berikut ini langkah-langkahnya.
1. publicint force;
2. Rigidbody2D rigid;
1. rigid =GetComponent<Rigidbody2D>();
2. Vector2 arah =newVector2(2,0).normalized;
3. rigid.AddForce(arah * force );
1. usingUnityEngine;
2. publicclassBallController:MonoBehaviour
3. {
4. publicint force;
5. Rigidbody2D rigid;
6. // Use this for initialization
7. voidStart()
8. {
9. rigid =GetComponent<Rigidbody2D>();
10. Vector2 arah =newVector2(2,0).normalized;
11. rigid.AddForce(arah * force);
12. }
13. // Update is called once per frame
14. voidUpdate()
15. {
16. }
17. }
Pembahasan
1. publicint force;
Dengan lewat inspector, nilai di atas untuk mengatur kecepatan gerak bola.
1. Rigidbody2D rigid;
1. rigid =GetComponent<Rigidbody2D>();
Menyatakan arah dari Force, yaitu 2 satuan ke kanan dan 0 satuan ke atas.
1. rigid.AddForce(arah * force);
Saat bola menyentuh tepi kanan dan tepi kiri, bola kembali ke posisi start. Jika bola mati di
sebelah kanan maka bola akan mengarah ke kanan. Begitupun sebaliknya, jika bola mati di
sebelah kiri maka bola akan mengarah ke kiri. Langkah-langkahnya sebagai berikut:
1. Buka Script BolaController.cs dengan klik 2 kali. Lalu tambahkan code sebagai berikut:
Tambahkan function di class BolaController
1. voidResetBall()
2. {
3. transform.localPosition =newVector2(0,0);
4. rigid.velocity =newVector2(0,0);
5. }
Tambahkan function OnCollisionEnter2D di class BolaController
1. privatevoidOnCollisionEnter2D(Collision2D coll)
2. {
3. if(coll.gameObject.name =="TepiKanan"){
4. ResetBall();
5. Vector2 arah =newVector2(2,0).normalized;
6. rigid.AddForce(arah * force);
7. }
8. if(coll.gameObject.name =="TepiKiri"){
9. ResetBall();
10. Vector2 arah =newVector2(-2,0).normalized;
11. rigid.AddForce(arah * force);
12. }
13. }
1. usingUnityEngine;
2. publicclassBallController:MonoBehaviour
3. {
4. publicint force;
5. Rigidbody2D rigid;
6. // Use this for initialization
7. voidStart()
8. {
9. rigid =GetComponent<Rigidbody2D>();
10. Vector2 arah =newVector2(2,0).normalized;
11. rigid.AddForce(arah * force);
12. }
13. // Update is called once per frame
14. voidUpdate()
15. {
16. }
17. privatevoidOnCollisionEnter2D(Collision2D coll)
18. {
19. if(coll.gameObject.name =="TepiKanan"){
20. ResetBall();
21. Vector2 arah =newVector2(2,0).normalized;
22. rigid.AddForce(arah * force);
23. }
24. if(coll.gameObject.name =="TepiKiri"){
25. ResetBall();
26. Vector2 arah =newVector2(-2,0).normalized;
27. rigid.AddForce(arah * force);
28. }
29. }
30. voidResetBall()
31. {
32. transform.localPosition =newVector2(0,0);
33. rigid.velocity =newVector2(0,0);
34. }
35. }
Pembahasan
1. voidResetBall()
1. transform.localPosition =newVector2(0,0);
1. rigid.velocity =newVector2(0,0);
1. privatevoidOnCollisionEnter2D(Collision2D coll)
1. if(coll.gameObject.name =="TepiKanan")
1. ResetBall();
Menjalakan seluruh code yang terdapat ResetBall yang meliputi mengatur ulang
posisi bola dan pergerakan bola.
1. rigid.AddForce(arah * force);
Kita akan membuat sebuah pantulan berdasarkan posisi pantulan Bola terhadap posisi Paddle.
Jika bola mengenai samping/pinggir Paddle, maka bola akan terpantul miring.
Ada beberapa hal yang perlu diperhatikan.
Pantulan berdasarkan posisi bola mengenai Paddle. Sehingga posisi titik Paddle sebagai
acuan Pantulan bola. Jika bola mengenai bagian atas paddle maka nilainya lebih besar 0
sehingga memantul keatas dan jika bola mengenai bagian bawah Paddle maka nilainya
kurang dari 0 sehingga pantul kebawah.
Misalnya bola mengenai ujung atas Paddle yang di mana posisi y pada bola sebesar 5 dan
posisi Y pada paddle sebesar 1, maka dari kedua nilai tersebut terdapat perbedaan 5 - 1 = 4
(lebih besar nilai 0 maka bola dipantul keatas). Sedangkan jika posisi Y pada bola tepat
dengan posisi Paddle yaitu sama-sama 1 maka nilai selisih yang didapat adalah 0 (bola akan
dipantulkan lurus).
1. usingUnityEngine;
2. publicclassBallController:MonoBehaviour{
3. publicint force;
4. Rigidbody2D rigid;
5. // Use this for initialization
6. voidStart(){
7. rigid =GetComponent<Rigidbody2D>();
8. Vector2 arah =newVector2(2,0).normalized;
9. rigid.AddForce(arah * force);
10. }
11. // Update is called once per frame
12. voidUpdate(){
13. }
14. privatevoidOnCollisionEnter2D(Collision2D coll)
15. {
16. if(coll.gameObject.name =="TepiKanan")
17. {
18. ResetBall();
19. Vector2 arah =newVector2(2,0).normalized;
20. rigid.AddForce(arah * force);
21. }
22. if(coll.gameObject.name =="TepiKiri")
23. {
24. ResetBall();
25. Vector2 arah =newVector2(-2,0).normalized;
26. rigid.AddForce(arah * force);
27. }
28. if(coll.gameObject.name =="Pemukul1"|| coll.gameObject.name =="Pemukul2")
29. {
30. float sudut =(transform.position.y - coll.transform.position.y)*5f;
31. Vector2 arah =newVector2(rigid.velocity.x, sudut).normalized;
32. rigid.velocity =newVector2(0,0);
33. rigid.AddForce(arah * force *2);
34. }
35. }
36. voidResetBall()
37. {
38. transform.localPosition =newVector2(0,0);
39. rigid.velocity =newVector2(0,0);
40. }
41. }
Pembahasan
1. rigid.velocity =newVector2(0,0);
Jika Anda masih kurang nyaman dengan pergerakkan bola dan pergerakkan paddle, Anda
dapat buka panel Inspector pada masing masing gameobject tersebut.
Membuat Skor
Setelah gameplay sederhana dapat dimainkan, selanjutnya membuat Skor. Di bagian ini,
selain menghitung berapa skor yang diperoleh, kita juga mempelajari tentang UI, mengatur
UI, dan implementasi Font.
Penggunaan teks sangat berhubungan dengan font. Anda dapat menggunakan berbagai model
font untuk menampilkan sebuah teks. Ada beberapa hal untuk mendapatkan sebuah font.
Anda dapat mengunduh Font dari berbagai situs dari yang gratis dan berbayar. Jangan lupa
untuk perhatikan lisensinya sebelum menggunakan
Anda dapat menggunakan font dari Standard Asset Unity dengan mengimpor Utilities.
Anda dapat membuat font sendiri dengan menggunakan tools vector seperti Adobe illustrator,
dll.
Pastikan style font sesuai dengan style game Anda. Karena game pukul bola lebih terlihat
game klasik maka kita menggunakan font pixel.
1. Setelah Anda memiliki sebuah font, Buatlah Folder baru dengan nama Fonts
2. Tambahkan file font “joystix monospace.ttf” ke dalam folder Fonts. (Klik kanan > Import
New Asset… )
Sekarang Anda sudah memiliki font yang siap digunakan untuk UI Text
Kita akan menampilkan skor yang telah diperoleh, kemudian menampilkan skor tersebut
dengan UI Text. Langkah-langkahnya adalah sebagai berikut:
1. Tambahkan Teks baru dengan klik kanan pada Scene Main kemudian pilih GameObject >
UI > Text dan ubah nama GameObject Text menjadi Score1.
2. Klik Canvas. Pada Inspector atur UI Scale Mode di komponen Canvas Scaler
menjadi Scale With Screen. Atur Nilai Reference Resolution menjadi X: 1280 dan Y: 720
3. Klik Score1, kemudian pada Inspector,
Selanjutnya kita akan masuk ke scripting. Pertama, kita akan membuat variable untuk
menyimpan skor.
1. int scoreP1;
2. int scoreP2;
Tambahkan inisialisasi variable score di function Start()
1. scoreP1 =0;
2. scoreP2 =0;
Simpan perubahan dengan tekan Ctrl+S
Praktik 7.2 Penghitungan Score dan Reset Posisi Bola
penambahan scoreP1 dan scoreP2
1. scoreP1 +=1;
Tambahkan code ini ketika bola menyentuh Tepi Kiri
1. scoreP2 +=1;
Simpan perubahan dengan tekan Ctrl+S
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4. publicclassBallController:MonoBehaviour
5. {
6. publicint force;
7. Rigidbody2D rigid;
8. int scoreP1;
9. int scoreP2;
10. // Use this for initialization
11. voidStart()
12. {
13. rigid =GetComponent<Rigidbody2D>();
14. Vector2 arah =newVector2(2,0).normalized;
15. rigid.AddForce(arah * force);
16. scoreP1 =0;
17. scoreP2 =0;
18. }
19. // Update is called once per frame
20. voidUpdate()
21. {
22. }
23. privatevoidOnCollisionEnter2D(Collision2D coll)
24. {
25. if(coll.gameObject.name =="TepiKanan"){
26. scoreP1 +=1;
27. ResetBall();
28. Vector2 arah =newVector2(2,0).normalized;
29. rigid.AddForce(arah * force);
30. }
31. if(coll.gameObject.name =="TepiKiri"){
32. scoreP2 +=1;
33. ResetBall();
34. Vector2 arah =newVector2(-2,0).normalized;
35. rigid.AddForce(arah * force);
36. }
37. if(coll.gameObject.name =="Pemukul1"|| coll.gameObject.name =="Pemukul2"){
38. float sudut =(transform.position.y - coll.transform.position.y)*5f;
39. Vector2 arah =newVector2(rigid.velocity.x, sudut).normalized;
40. rigid.velocity =newVector2(0,0);
41. rigid.AddForce(arah * force *2);
42. }
43. }
44. voidResetBall()
45. {
46. transform.localPosition =newVector2(0,0);
47. rigid.velocity =newVector2(0,0);
48. }
49. }
Setelah menambahkan text (Score1 dan Score2 pada Canvas), kita perlu menampilkan score
yang diperhitungan ke layar. Penambahan score diatur dalam Script BallController.cs. Oleh
karena itu, penulisan skor juga akan ditangani dalam script ini. Langkah-langkahnya sebagai
berikut:
1. Buka Script BallController.cs dengan klik 2 kali. Kemudian tambahkan kode sebagai
berikut:
1. usingUnityEngine.UI;
Tambahkan Variable di dalam class BallController
1. Text scoreUIP1;
2. Text scoreUIP2;
Tambahkan Inisialisasi variable scoreUIP1 dan scrore UIP2
1. scoreUIP1 =GameObject.Find("Score1").GetComponent<Text>();
2. scoreUIP2 =GameObject.Find("Score2").GetComponent<Text>();
Tambahkan function di dalam class BallController
1. voidTampilkanScore()
2. {
3. Debug.Log("Score P1: "+ scoreP1 +" Score P2: "+ scoreP2);
4. scoreUIP1.text = scoreP1 +"";
5. scoreUIP2.text = scoreP2 +"";
6. }
Tambahkan code ini ketika penambahkan scoreP1 dan scoreP2
1. TampilkanScore();
Simpan perubahan dengan tekan Ctrl+S sehingga seluruh code menjadi seperti berikut:
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4. usingUnityEngine.UI;
5. publicclassBallController:MonoBehaviour
6. {
7. publicint force;
8. Rigidbody2D rigid;
9. int scoreP1;
10. int scoreP2;
11. Text scoreUIP1;
12. Text scoreUIP2;
13. // Use this for initialization
14. voidStart()
15. {
16. rigid =GetComponent<Rigidbody2D>();
17. Vector2 arah =newVector2(2,0).normalized;
18. rigid.AddForce(arah * force);
19. scoreP1 =0;
20. scoreP2 =0;
21. scoreUIP1 =GameObject.Find("Score1").GetComponent<Text>();
22. scoreUIP2 =GameObject.Find("Score2").GetComponent<Text>();
23. }
24. // Update is called once per frame
25. voidUpdate()
26. {
27. }
28. privatevoidOnCollisionEnter2D(Collision2D coll)
29. {
30. if(coll.gameObject.name =="TepiKanan"){
31. scoreP1 +=1;
32. TampilkanScore();
33. ResetBall();
34. Vector2 arah =newVector2(2,0).normalized;
35. rigid.AddForce(arah * force);
36. }
37. if(coll.gameObject.name =="TepiKiri"){
38. scoreP2 +=1;
39. TampilkanScore();
40. ResetBall();
41. Vector2 arah =newVector2(-2,0).normalized;
42. rigid.AddForce(arah * force);
43. }
44. if(coll.gameObject.name =="Pemukul1"|| coll.gameObject.name =="Pemukul2"){
45. float sudut =(transform.position.y - coll.transform.position.y)*5f;
46. Vector2 arah =newVector2(rigid.velocity.x, sudut).normalized;
47. rigid.velocity =newVector2(0,0);
48. rigid.AddForce(arah * force *2);
49. }
50. }
51. voidResetBall()
52. {
53. transform.localPosition =newVector2(0,0);
54. rigid.velocity =newVector2(0,0);
55. }
56. voidTampilkanScore()
57. {
58. Debug.Log("Score P1: "+ scoreP1 +" Score P2: "+ scoreP2);
59. scoreUIP1.text = scoreP1 +"";
60. scoreUIP2.text = scoreP2 +"";
61. }
62. }
Pembahasan
using UnityEngine.UI;
Text scoreUIP1;
Text scoreUIP2;
scoreUIP1 = GameObject.Find("Score1").GetComponent<Text>();
scoreUIP2 = GameObject.Find("Score2").GetComponent<Text>();
Digunakan untuk mengakses GameObject yang memiliki Nama Score1 dan Score 2.
Kemudian dari GameObject tersebut di cari komponen Text yang ada didalamnya yang
kemudian di simpan ke scoreUIP1 dan Score UIP2.
void TampilkanScore() {
}
1. Tambahkan UI Panel pada Canvas dengan cara Klik Kanan pada Canvas kemudian
pilih UI > Panel. Ubah Nama dari Panel menjadi PanelSelesai.
2. Atur warna pada PanelSelesai dengan warna yang lebih gelap. Tujuannya, agar tekst yang
diatasnya lebih dapat terbaca)
3. Tambahkan 2 Text di dalam Panel (Klik kanan pada PanelSelesai, Pilih UI > Text)
Jangan lupa untuk mengatur posisi dan width dan height pada Rect Transform
4. Tambahkan 2 Button di dalam PanelSelesai (Klik kanan pada Panel selesai > UI > Button)
Aturlah kedua Text sebagai berikut:
Button 1
o Nama Object: BtnMenu
o Width: > 271
o Height: > 92
o Source Image: Persegi
o Normal Color: Putih
o Pressed Color: Oranye
Text pada Botton 1
o Text: Kembali Ke Main Manu
o Font: joystix monospace
o Font Size: 26
o Alignment: Center-Center
o Color: Hitam
Button 2
o Nama Object: BtnUlangi
o Width: > 271
o Height: > 92
o Source Image: Persegi
o Normal Color: Putih
o Pressed Color: Oranye
Text pada Botton 2
o Text: Ulangi Permainan
o Font: joystix monospace
o Font Size: 26
o Alignment: Center-Center
o Color: Hitam
Setelah halaman selesai selanjutnya membuat kondisi jika salah satu player memiliki skor 5
maka dia menjadi pemenang. Sehingga memiliki Alur sebagai berikut:
Tampilan Score
Jika memiliki 5 skor maka tampilkan halaman Selesai dan hentikan permainan
(Menghilangkan bola)
1. GameObject panelSelesai;
2. Text txPemenang;
Tambahkan inisialisasi variable panelSelesai tersebut di function Start()
1. panelSelesai =GameObject.Find("PanelSelesai");
2. panelSelesai.SetActive(false);
Tambahkan kode ini setelah menampilkan skor saat bola menyentuh tepi kanan
1. if(scoreP1 ==5){
2. panelSelesai.SetActive(true);
3. txPemenang =GameObject.Find("Pemenang").GetComponent<Text>();
4. txPemenang.text ="Player Biru Pemenang!";
5. Destroy(gameObject);
6. return;
7. }
Tambahkan code ini setelah menampilkan score ketika bola menyentuh tepi kiri
1. if(scoreP2 ==5){
2. panelSelesai.SetActive(true);
3. txPemenang =GameObject.Find("Pemenang").GetComponent<Text>();
4. txPemenang.text ="Player Merah Pemenang!";
5. Destroy(gameObject);
6. return;
7. }
Simpan dengan tekan Ctrl+S
1. usingSystem.Collections;
2. usingSystem.Collections.Generic;
3. usingUnityEngine;
4. usingUnityEngine.UI;
5.
6.
7. publicclassBallController:MonoBehaviour
8. {
9.
10.
11. publicint force;
12. Rigidbody2D rigid;
13.
14.
15. int scoreP1;
16. int scoreP2;
17.
18.
19. Text scoreUIP1;
20. Text scoreUIP2;
21.
22.
23. GameObject panelSelesai;
24. Text txPemenang;
25.
26.
27. // Use this for initialization
28. voidStart()
29. {
30. rigid =GetComponent<Rigidbody2D>();
31. Vector2 arah =newVector2(2,0).normalized;
32. rigid.AddForce(arah * force);
33.
34.
35. scoreP1 =0;
36. scoreP2 =0;
37.
38.
39. scoreUIP1 =GameObject.Find("Score1").GetComponent<Text>();
40. scoreUIP2 =GameObject.Find("Score2").GetComponent<Text>();
41.
42.
43. panelSelesai =GameObject.Find("PanelSelesai");
44. panelSelesai.SetActive(false);
45. }
46.
47.
48. // Update is called once per frame
49. voidUpdate()
50. {
51.
52.
53. }
54.
55.
56. privatevoidOnCollisionEnter2D(Collision2D coll)
57. {
58. if(coll.gameObject.name =="TepiKanan"){
59. scoreP1 +=1;
60. TampilkanScore();
61. if(scoreP1 ==5){
62. panelSelesai.SetActive(true);
63. txPemenang =GameObject.Find("Pemenang").GetComponent<Text>();
64. txPemenang.text ="Player Biru Pemenang!";
65. Destroy(gameObject);
66. return;
67. }
68. ResetBall();
69. Vector2 arah =newVector2(2,0).normalized;
70. rigid.AddForce(arah * force);
71. }
72.
73.
74. if(coll.gameObject.name =="TepiKiri"){
75. scoreP2 +=1;
76. TampilkanScore();
77. if(scoreP2 ==5){
78. panelSelesai.SetActive(true);
79. txPemenang =GameObject.Find("Pemenang").GetComponent<Text>();
80. txPemenang.text ="Player Merah Pemenang!";
81. Destroy(gameObject);
82. return;
83. }
84. ResetBall();
85. Vector2 arah =newVector2(-2,0).normalized;
86. rigid.AddForce(arah * force);
87. }
88.
89.
90. if(coll.gameObject.name =="Pemukul1"|| coll.gameObject.name =="Pemukul2"){
91. float sudut =(transform.position.y - coll.transform.position.y)*5f;
92. Vector2 arah =newVector2(rigid.velocity.x, sudut).normalized;
93. rigid.velocity =newVector2(0,0);
94. rigid.AddForce(arah * force *2);
95. }
96.
97.
98. }
99.
100.
101. voidResetBall()
102. {
103. transform.localPosition =newVector2(0,0);
104. rigid.velocity =newVector2(0,0);
105. }
106.
107.
108. voidTampilkanScore()
109. {
110. Debug.Log("Score P1: "+ scoreP1 +" Score P2: "+ scoreP2);
111. scoreUIP1.text = scoreP1 +"";
112. scoreUIP2.text = scoreP2 +"";
113. }
114. }
Pembahasan
1. GameObject panelSelesai;
2. Text txPemenang;
1. panelSelesai =GameObject.Find("PanelSelesai");
2. panelSelesai.SetActive(false);
1. if(scoreP1 ==5)
1. panelSelesai.SetActive(true);
1. txPemenang =GameObject.Find("Pemenang").GetComponent<Text>();
1. Destroy(gameObject);
Hilangkan Bola
1. Return;
Di pembelajaran ini kita hanya menggunakan satu tombol untuk masuk ke permainan. Selain
membuat halaman utama juga mengatur perpindahan halaman baik di halaman utama
maupun di halaman selesai.
Text 1
o Nama Object: Judul
o Text: Pukul Bola
o Font: joystix monospace
o Font size: 96
o Alignment: Center - Center
o Color: Putih
Button 1
o Nama Object: btnMulai
o Width: > 400
o Height: > 150
o Source Image: Persegi
o Normal Color: Putih
o Pressed Color: Oranye
Text pada Botton 1
o Text: Mulai!
o Font: joystix monospace
o Font Size: 60
o Alignment: Center-Center
o Color: Hitam
1. usingUnityEngine.SceneManagement;
Tambahkan variable di dalam class HalamanManager
1. publicbool isEscapeToExit;
Tambahkan 2 function kedalam class HalamanManager
1. publicvoidMulaiPermainan()
2. {
3. SceneManager.LoadScene("Main");
4. }
5. publicvoidKembaliKeMenu()
6. {
7. SceneManager.LoadScene("Menu");
8. }
Tambahkan code ini di dalam function Update
1. if(Input.GetKeyUp(KeyCode.Escape)){
2. if(isEscapeToExit){
3. Application.Quit();
4. }else{
5. KembaliKeMenu();
6. }
7. }
1. usingUnityEngine;
2. usingUnityEngine.SceneManagement;
3. publicclassHalamanManager:MonoBehaviour
4. {
5. publicbool isEscapeToExit;
6. // Use this for initialization
7. voidStart()
8. {
9. }
10. // Update is called once per frame
11. voidUpdate()
12. {
13. if(Input.GetKeyUp(KeyCode.Escape)){
14. if(isEscapeToExit){
15. Application.Quit();
16. }else{
17. KembaliKeMenu();
18. }
19. }
20. }
21. publicvoidMulaiPermainan()
22. {
23. SceneManager.LoadScene("Main");
24. }
25. publicvoidKembaliKeMenu()
26. {
27. SceneManager.LoadScene("Menu");
28. }
29. }
Pembahasan
1. usingUnityEngine.SceneManagement;
1. publicbool isEscapeToExit;
Digunakan untuk menentukan fungsi tombol Escape untuk kembali ke Menu atau ke
Main (Gameplay)
1. publicvoidMulaiPermainan(){
2. SceneManager.LoadScene("Main");
3. }
1. publicvoidKembaliKeMenu(){
2. SceneManager.LoadScene("Menu");
3. }
1. if(Input.GetKeyUp(KeyCode.Escape))
2. {
3. if(isEscapeToExit)
4. {
5. Application.Quit();
6. }
7. else
8. {
9. KembaliKeMenu();
10. }
11. }
Setelah Anda memaskkan script ke gameobject. pada Inspector, centang “Is Escape to Exit.”
Sehingga ketika user menekan tombol escape maka akan keluar dari aplikasi
Praktik: Daftarkan Semua Scene ke Scenes In Build
Scene yang telah dibuat, tidak dapat langsung diakses. Kita sudah memiliki 2 Scene. Kedua
scene tersebutt harus dimasukkan terlebih dahulu ke Scenes In Build.
Setelah script sudah dibuat dan scene sudah siap, selanjutnya hubungkan script yang telah
dibuat ke Button (btnMulai). Langkah-langkahnya antara lain:
1. Klik btnMulai, kemudian pada komponen Button di panel Inspector. Klik icon + pada
On Click().
Ketika mejalankan dari scene menu, kemudian klik tombol mulai maka akan membuka
halaman permainan pada scene Main.
Menambahkan Audio
Menuju bagian akhir dari modul ini, kali ini kita akan belajar menambahkan audio agar game
yang dibuat lebih hidup. Dalam tutorial ini, audio akan digunakan sebagai:
Background music
Sound effect ketika bola terpantul
Salah satu tempat yang menyediakan audio gratis adalah Audio Library – No Copyright
Music (https://www.youtube.com/channel/UCht8qITGkBvXKsR1Byln-wA). Sebagai
sampel, sound berikut ini yang akan kita gunakan.
Silakan gunakan audio lain yang Anda inginkan, tetapi perhatikan lisensinya ya. Jika ingin
konversi dari mp4 ke mp3, gunakan Online Video
Converter (https://www.onlinevideoconverter.com/mp3-converter).
Setelah mengunduh audio pilihan, buat folder Audios serta drag and drop berkas audio
tersebut ke folder tersebut.
Pada Unity, terdapat beberapa istilah yang berkaitan dengan Audio. Beberapa istilah yang
penting yaitu:
Audio Listener
Audio Source
Audio Source merupakan Component yang memutar sebuah Audio Clip pada Scene.
Efek audio bisa ditambahkan pada Audio Source.
Audio Clip
Audio Clip berisi data audio yang akan digunakan oleh Audio Source. Format audio
yang ada dalam Unity yaitu: .aif, .wav, .mp3, and .ogg.
1. Buka Scene Main. lalu Klik Main Camera di Hierarchy, kemudian pada Inspector
tambahkan Audio Source (Add Component > Audio > Audio Source)
2. Masukkan berkas “Bike_Rides.mp3” ke field Audio Clip. Jangan lupa untuk centang
Loop
Ketika dimainkan, musik langsung jalan, dan secara otomatis mengulang ketika selesai. Anda
juga dapat mengatur Volume untuk menyesuaikan kenyamanan pada game yang Anda buat.
Penambahan sound effect akan dicontohkan dengan momen ketika Bola menabrak benda
lain. Langkah-langkah yang diperlukan cukup mirip dengan penambahan background music,
yaitu:
1. AudioSource audio;
2. publicAudioClip hitSound;
Pada prosedur Start(), tambahkan:
1. audio =GetComponent<AudioSource>();
1. audio.PlayOneShot(hitSound);
Simpan perubahan dengan tekan Ctrl+S
1. usingUnityEngine;
2. usingUnityEngine.UI;
3. publicclassBallController:MonoBehaviour
4. {
5. publicint force;
6. Rigidbody2D rigid;
7. int scoreP1;
8. int scoreP2;
9. Text scoreUIP1;
10. Text scoreUIP2;
11. GameObject panelSelesai;
12. Text txPemenang;
13. AudioSource audio;
14. publicAudioClip hitSound;
15. // Use this for initialization
16. voidStart()
17. {
18. rigid =GetComponent<Rigidbody2D>();
19. Vector2 arah =newVector2(2,0).normalized;
20. rigid.AddForce(arah * force);
21. scoreP1 =0;
22. scoreP2 =0;
23. scoreUIP1 =GameObject.Find("Score1").GetComponent<Text>();
24. scoreUIP2 =GameObject.Find("Score2").GetComponent<Text>();
25. panelSelesai =GameObject.Find("PanelSelesai");
26. panelSelesai.SetActive(false);
27. audio =GetComponent<AudioSource>();
28. }
29. // Update is called once per frame
30. voidUpdate()
31. {
32. }
33. privatevoidOnCollisionEnter2D(Collision2D coll)
34. {
35. audio.PlayOneShot(hitSound);
36. if(coll.gameObject.name =="TepiKanan"){
37. scoreP1 +=1;
38. TampilkanScore();
39. if(scoreP1 ==5){
40. panelSelesai.SetActive(true);
41. txPemenang =GameObject.Find("Pemenang").GetComponent<Text>();
42. txPemenang.text ="Player Biru Pemenang!";
43. Destroy(gameObject);
44. return;
45. }
46. ResetBall();
47. Vector2 arah =newVector2(2,0).normalized;
48. rigid.AddForce(arah * force);
49. }
50. if(coll.gameObject.name =="TepiKiri"){
51. scoreP2 +=1;
52. TampilkanScore();
53. if(scoreP2 ==5){
54. panelSelesai.SetActive(true);
55. txPemenang =GameObject.Find("Pemenang").GetComponent<Text>();
56. txPemenang.text ="Player Merah Pemenang!";
57. Destroy(gameObject);
58. return;
59. }
60. ResetBall();
61. Vector2 arah =newVector2(-2,0).normalized;
62. rigid.AddForce(arah * force);
63. }
64. if(coll.gameObject.name =="Pemukul1"|| coll.gameObject.name =="Pemukul2"){
65. float sudut =(transform.position.y - coll.transform.position.y)*5f;
66. Vector2 arah =newVector2(rigid.velocity.x, sudut).normalized;
67. rigid.velocity =newVector2(0,0);
68. rigid.AddForce(arah * force *2);
69. }
70. }
71. voidResetBall()
72. {
73. transform.localPosition =newVector2(0,0);
74. rigid.velocity =newVector2(0,0);
75. }
76. voidTampilkanScore()
77. {
78. Debug.Log("Score P1: "+ scoreP1 +" Score P2: "+ scoreP2);
79. scoreUIP1.text = scoreP1 +"";
80. scoreUIP2.text = scoreP2 +"";
81. }
82. }
Pembahasan:
1. AudioSource audio;
1. publicAudioClip hitSound;
1. audio.PlayOneShot(hitSound);
Anda juga dapat mengatur Volume dan Pitch untuk menyesuaikan gameplay yang Anda buat.
Submission
Selamat, Anda telah menyelesaikan materi dalam kelas Belajar Membuat Game Untuk
Pemula. Untuk lulus dan mendapatkan sertifikat dari Akademi ini, Anda harus
mengumpulkan Tugas Akhir berupa game yang Anda buat sendiri.
Game tersebut dibuat dengan memanfaatkan materi pada modul yang telah Anda pelajari
sebelumnya. Atau, Anda juga dapat mengembangkannya menjadi lebih menarik.
Resources Asset 2D
http://www.gameart2d.com/freebies.html
https://kenney.nl/assets
Kirimkan berkas project Anda (Hanya folder Assets dan folder ProjectSettings)
Semua berkas dalam bentuk satu Zip.
Jika Anda gagal mengunggah tugas, Anda dapat mengunggahnya menggunakan via Dropbox
atau Google Drive.
Submission anda akan dinilai / direview secara manual oleh tim penilai dalam
maksimal 3 (tiga) hari kerja (tidak termasuk sabtu, minggu, dan hari libur nasional).