Ini adalah bagian kedua dari tutorial 
“Membuat game Tower Defense di Unity” . Kami membuat game bergenre tower defense di Unity, dan pada akhir bagian 
pertama , kami belajar cara menempatkan dan meningkatkan monster. Kami juga memiliki satu cookie yang menyerang musuh.
Namun, musuh belum tahu ke mana harus mencari! Selain itu, serangan saja terlihat aneh. Di bagian tutorial ini, kami akan menambahkan gelombang musuh dan monster lengan sehingga mereka dapat mempertahankan cookie yang berharga.
Mulai bekerja
Buka proyek di Unity, yang kami hentikan di bagian terakhir. Jika Anda bergabung dengan kami sekarang, unduh 
konsep proyek dan buka 
TowerDefense-Part2-Starter .
Buka 
GameScene dari folder 
Adegan .
Ubah musuh
Pada akhir tutorial sebelumnya, musuh belajar bergerak di sepanjang jalan, tetapi tampaknya ia tidak tahu ke mana harus mencari.
Buka skrip 
MoveEnemy.cs di IDE dan tambahkan metode berikut untuk memperbaiki situasi.
private void RotateIntoMoveDirection() {  
RotateIntoMoveDirection memutar musuh sehingga selalu 
RotateIntoMoveDirection ke depan. Dia melakukannya sebagai berikut:
- Menghitung arah bug saat ini, mengurangi posisi titik jalan saat ini dari posisi titik berikutnya.
- Menggunakan Mathf.Atan2untuk menentukan sudut dalam radian di mana diarahkan arah baru (titik nol di sebelah kanan).180 / Mathf.PIhasilnya dengan180 / Mathf.PI, mengubah sudut menjadi derajat.
- Akhirnya, ia mendapatkan anak Sprite dan memutar derajat rotationAnglesumbu. Perhatikan bahwa kita memutar anak , bukan orang tua, sehingga strip energi yang kita tambahkan nanti tetap horisontal.
Di 
Update() , ganti komentar 
// TODO: panggilan berikutnya ke 
RotateIntoMoveDirection :
 RotateIntoMoveDirection(); 
Simpan file dan kembali ke Unity. Jalankan adegan; sekarang musuh tahu ke mana dia bergerak.
Sekarang bug tahu ke mana ia pergi.
Musuh satu-satunya tidak terlihat sangat mengesankan. Kami membutuhkan gerombolan! Dan seperti dalam setiap game menara pertahanan, gerombolan berlari dalam gelombang!
Menginformasikan pemain
Sebelum kita mulai menggerakkan gerombolan, kita perlu memperingatkan pemain tentang pertempuran yang akan datang. Selain itu, ada baiknya menampilkan nomor gelombang saat ini di bagian atas layar.
Informasi 
Wave diperlukan oleh beberapa GameObjects, jadi kami akan menambahkannya ke komponen 
GameManagerBehavior dari 
GameManager .
Buka 
GameManagerBehavior.cs di IDE dan tambahkan dua variabel berikut:
 public Text waveLabel; public GameObject[] nextWaveLabels; 
waveLabel menyimpan tautan ke label output nomor gelombang di sudut kanan atas layar. 
nextWaveLabels menyimpan dua GameObjects yang membuat kombinasi animasi yang akan kami tampilkan di awal gelombang baru:
Simpan file dan kembali ke Unity. Pilih 
GameManager di 
Hirarki . Klik lingkaran di sebelah kanan 
Wave Label dan di kotak dialog 
Select Text , pilih 
WaveLabel dari tab 
Scene .
Sekarang atur 
Label Ukuran untuk 
Gelombang Selanjutnya ke 
2 . Sekarang atur 
Elemen 0 ke 
NextWaveBottomLabel , dan untuk 
Elemen 1 NextWaveTopLabel sama seperti yang kita lakukan dengan Wave Label.
Seperti inilah perilaku Manajer Game sekarangJika pemain kalah, maka dia seharusnya tidak melihat pesan tentang gelombang berikutnya. Untuk menangani situasi ini, kembali ke 
GameManagerBehavior.cs dan tambahkan variabel lain:
 public bool gameOver = false; 
Di 
gameOver kami akan menyimpan nilai apakah pemain kalah.
Di sini kita kembali menggunakan properti untuk menyinkronkan elemen-elemen permainan dengan gelombang saat ini. Tambahkan kode berikut ke 
GameManagerBehavior :
 private int wave; public int Wave { get { return wave; } set { wave = value; if (!gameOver) { for (int i = 0; i < nextWaveLabels.Length; i++) { nextWaveLabels[i].GetComponent<Animator>().SetTrigger("nextWave"); } } waveLabel.text = "WAVE: " + (wave + 1); } } 
Membuat variabel pribadi, properti, dan pengambil harus sudah menjadi hal yang akrab bagi Anda. Tetapi dengan setter, sekali lagi, semuanya sedikit lebih menarik.
Kami memberikan 
wave value baru.
Kemudian kami memeriksa apakah game sudah selesai. Jika tidak, maka lewati semua label 
NextLaveLabel - label ini memiliki komponen 
Animator . Untuk mengaktifkan animasi 
Animator , kami 
menetapkan pemicu 
Gelombang berikutnya .
Terakhir, kami mengatur 
text waveLabel ke 
wave + 1 . Mengapa memberi 
+1 ? Orang biasa tidak mulai menghitung dari awal (ya, ini aneh).
Di 
Start() mengatur nilai properti ini:
 Wave = 0; 
Kami memulai penghitungan dengan angka 
0 Wave .
Simpan file dan jalankan adegan di Unity. Label Wave akan menunjukkan dengan benar 1.
Untuk seorang pemain, semuanya dimulai dengan gelombang 1.Gelombang: membuat banyak musuh
Ini mungkin terlihat jelas, tetapi untuk menyerang dengan gerombolan perlu untuk membuat lebih banyak musuh - sementara kita tidak tahu bagaimana melakukan ini. Selain itu, kita tidak harus membuat gelombang berikutnya sampai yang sekarang dihancurkan.
Artinya, gim harus bisa mengenali keberadaan musuh di TKP, dan 
tag adalah cara yang baik untuk mengidentifikasi objek gim di sini.
Penandaan musuh
Pilih prefab 
Musuh di Browser Proyek. Di bagian atas 
Inspektur, klik pada daftar drop-down 
Tag dan pilih 
Add Tag .
Buat 
tag yang disebut 
Musuh .
Pilih 
Musuh cetakan. Di 
Inspektur, atur 
tag Musuh untuknya.
Mendefinisikan gelombang musuh
Sekarang kita perlu mengatur gelombang musuh. Buka 
SpawnEnemy.cs di IDE dan tambahkan implementasi kelas berikut sebelum 
SpawnEnemy :
 [System.Serializable] public class Wave { public GameObject enemyPrefab; public float spawnInterval = 2; public int maxEnemies = 20; } 
Wave berisi 
enemyPrefab - dasar untuk membuat instance dari semua musuh dalam wave ini, 
spawnInterval - waktu antara musuh dalam wave dalam hitungan detik dan 
maxEnemies - jumlah musuh yang dibuat dalam wave ini.
Kelas 
Serializable , yaitu, kita dapat mengubah nilainya di Inspektur.
Tambahkan variabel berikut ke kelas 
SpawnEnemy :
 public Wave[] waves; public int timeBetweenWaves = 5; private GameManagerBehavior gameManager; private float lastSpawnTime; private int enemiesSpawned = 0; 
Di sini kita mengatur variabel untuk memunculkan musuh, yang sangat mirip dengan bagaimana kita memindahkan musuh di antara titik-titik pada rute.
Kami mengatur gelombang masing-masing musuh dalam 
waves dan melacak jumlah musuh yang dibuat dan waktu mereka diciptakan dalam 
enemiesSpawned dan 
lastSpawnTime .
Setelah semua pembunuhan ini, pemain perlu waktu untuk bernapas, jadi atur waktu antara 
timeBetweenWaves ke 5 detik.
Ganti konten 
Start() kode berikut.
 lastSpawnTime = Time.time; gameManager = GameObject.Find("GameManager").GetComponent<GameManagerBehavior>(); 
Di sini kita menetapkan 
lastSpawnTime nilai waktu saat ini, yaitu waktu script dimulai setelah adegan dimuat. Lalu kita dapatkan 
GameManagerBehavior sudah akrab.
Tambahkan kode berikut ke 
Update() :
 
Mari kita analisa langkah demi langkah:
- Kami mendapatkan indeks gelombang saat ini dan memeriksa apakah itu yang terakhir.
- Jika demikian, maka kami menghitung waktu yang telah berlalu setelah musuh sebelumnya muncul dan memeriksa apakah sudah waktunya untuk membuat musuh. Di sini kita memperhitungkan dua kasus. Jika ini adalah musuh pertama dalam wave, maka kami memeriksa apakah timeIntervaldaritimeBetweenWaves. Jika tidak, kami memeriksa apakahtimeIntervaldarispawnIntervalwave. Bagaimanapun, kami memeriksa bahwa kami belum menciptakan semua musuh di gelombang ini.
- Jika perlu, buat musuh, buat instance dari enemyPrefab. Juga tingkatkan nilaienemiesSpawned.
- Periksa jumlah musuh di layar. Jika mereka tidak ada di sana, dan ini adalah musuh terakhir dalam gelombang, maka kita buat gelombang berikutnya. Juga di akhir gelombang, kami memberi pemain 10 persen dari semua emas yang tersisa.
- Setelah mengalahkan gelombang terakhir, animasi kemenangan dalam permainan dimainkan di sini.
Mengatur interval spawn
Simpan file dan kembali ke Unity. Pilih objek 
Jalan di 
Hirarki . Di 
Inspektur, atur objek 
Size of the 
Waves ke 
4 .
Untuk saat ini, pilih objek 
Musuh untuk keempat elemen sebagai 
Prefab Musuh . Konfigurasikan bidang 
Spawn Interval dan 
Max Enemies sebagai berikut:
- Elemen 0 : Spawn Interval: 2.5 , Max Enemies: 5
- Elemen 1 : Interval Spawn: 2 , Max Musuh: 10
- Elemen 2 : Interval Spawn: 2 , Max Musuh: 15
- Elemen 3 : Interval Spawn: 1 , Max Musuh: 5
Skema yang sudah selesai akan terlihat seperti ini:
Tentu saja, Anda dapat bereksperimen dengan nilai-nilai ini untuk menambah atau mengurangi kompleksitas.
Luncurkan game. Ya! Kumbang telah memulai perjalanan ke cookie Anda!
Tugas tambahan: tambahkan berbagai jenis musuh
Tidak ada game menara pertahanan yang dapat dianggap lengkap hanya dengan satu jenis musuh. Untungnya, ada juga 
Enemy2 di folder 
Rak itan .
Di 
Inspektur, pilih 
Rak itan \ Enemy2 dan tambahkan skrip 
MoveEnemy ke sana. Setel 
Kecepatan ke 
3 dan atur 
tag Musuh . Sekarang Anda dapat menggunakan musuh cepat ini sehingga pemain tidak rileks!
Pembaruan Kehidupan Pemain
Meskipun gerombolan musuh menyerang cookie, pemain tidak mengalami kerusakan. Tapi segera kami akan memperbaikinya. Pemain harus menderita jika dia membiarkan musuh menyelinap.
Buka 
GameManagerBehavior.cs di IDE dan tambahkan dua variabel berikut:
 public Text healthLabel; public GameObject[] healthIndicator; 
Kami menggunakan 
healthLabel untuk mengakses nilai kehidupan pemain, dan 
healthIndicator untuk mengakses lima monster hijau kecil yang mengunyah cookie - mereka hanya melambangkan kesehatan pemain; ini lebih lucu daripada indikator kesehatan standar.
Manajemen kesehatan
Sekarang tambahkan properti yang menyimpan kesehatan pemain di 
GameManagerBehavior :
 private int health; public int Health { get { return health; } set {  
Inilah cara kami mengelola kesehatan pemain. Dan lagi, bagian utama dari kode terletak di setter:
- Jika kami mengurangi kesehatan pemain, kami menggunakan komponen CameraShakeuntuk menciptakan efek getaran yang indah. Skrip ini termasuk dalam proyek yang dapat diunduh dan kami tidak akan mempertimbangkannya di sini.
- Kami memperbarui variabel pribadi dan label kesehatan di sudut kiri atas layar.
- Jika kesehatan turun ke 0 dan akhir game belum datang, maka gameOvermenjaditruedan mulai animasigameOver.
- Kami menghapus salah satu monster dari cookie. Jika kita mematikannya, maka bagian ini dapat ditulis lebih mudah, tetapi di sini kami mendukung inklusi kembali jika kesehatan ditambahkan.
Kami menginisialisasi 
Health in 
Start() :
 Health = 5; 
Kami menetapkan 
Health ke 
5 saat adegan mulai diputar.
Setelah melakukan semua ini, kami sekarang dapat memperbarui kesehatan pemain ketika bug sampai ke cookie. Simpan file dan pergi ke IDE ke skrip 
MoveEnemy.cs .
Perubahan kesehatan
Untuk mengubah kesehatan Anda, temukan komentar di 
Update() dengan kata-kata 
// TODO: dan ganti dengan kode ini:
 GameManagerBehavior gameManager = GameObject.Find("GameManager").GetComponent<GameManagerBehavior>(); gameManager.Health -= 1; 
Jadi kami mendapatkan 
GameManagerBehavior dan mengurangi unit dari 
Health .
Simpan file dan kembali ke Unity.
Pilih 
GameManager di 
Hierarchy dan pilih 
HealthLabel untuk 
Label Kesehatannya .
Perluas objek 
Cookie di 
Hierarchy dan seret 
HealthIndikatorator lima anaknya ke dalam array 
Indikator Kesehatan GameManager - indikator kesehatan akan berupa monster hijau kecil yang memakan cookie.
Jalankan adegan dan tunggu sampai bug mencapai cookie. Jangan lakukan apa pun sampai Anda kalah.
Balas dendam monster
Monster di tempat? Ya Apakah musuh menyerang? Ya, dan mereka terlihat mengancam! Sudah waktunya untuk menjawab hewan-hewan ini!
Untuk melakukan ini, kita perlu yang berikut:
- Jalur kesehatan sehingga pemain tahu musuh mana yang kuat dan mana yang lemah
- Mendeteksi musuh dalam jangkauan monster
- Membuat keputusan - musuh yang akan ditembak
- Banyak kerang
Bilah kesehatan musuh
Untuk menerapkan pita kesehatan, kami menggunakan dua gambar - satu untuk latar belakang gelap, dan yang kedua (bilah hijau sedikit lebih kecil) kami akan skala sesuai dengan kesehatan musuh.
Seret dari 
Browser Proyek ke adegan 
Prefab \ Musuh .
Kemudian di 
Hierarki, seret dan lepas 
Gambar \ Objek \ HealthBarBackground ke 
Musuh untuk menambahkannya sebagai seorang anak.
Di 
Inspektur, atur 
Posisi HealthBarBackground ke 
(0, 1, -4) .
Kemudian di 
Browser Proyek, pilih 
Gambar \ Objek \ HealthBar dan pastikan 
Pivot -nya adalah 
Kiri . Kemudian tambahkan sebagai anak 
Musuh dalam 
Hirarki dan tetapkan nilai 
Posisinya (-0,63, 1, -5) . Untuk 
Skala X , atur nilainya menjadi 
125 .
Tambahkan skrip 
C # baru yang disebut 
HealthBar ke objek game 
HealthBar . Nanti kita akan mengubahnya sehingga mengubah panjang bar kesehatan.
Setelah memilih objek 
Musuh dalam 
Hirarki , pastikan posisinya adalah 
(20, 0, 0) .
Klik 
Terapkan di bagian atas 
Inspektur untuk menyimpan semua perubahan sebagai bagian dari cetakan. Akhirnya, hapus objek 
Musuh dalam 
Hirarki .
Sekarang ulangi semua langkah ini untuk menambahkan bilah kesehatan untuk 
Prefabs \ Enemy2 .
Ubah panjang bilah kesehatan
Buka IDE 
HealthBar.cs dan tambahkan variabel berikut:
 public float maxHealth = 100; public float currentHealth = 100; private float originalScale; 
Di 
maxHealth , kesehatan maksimum musuh disimpan, dan di saat ini, 
currentHealth - kesehatan yang tersisa. Akhirnya, dalam 
originalScale adalah ukuran awal bar kesehatan.
Simpan objek 
originalScale di 
Start() :
 originalScale = gameObject.transform.localScale.x; 
Kami menyimpan nilai 
x properti 
localScale .
Tetapkan skala bilah kesehatan dengan menambahkan kode berikut ke 
Update() :
 Vector3 tmpScale = gameObject.transform.localScale; tmpScale.x = currentHealth / maxHealth * originalScale; gameObject.transform.localScale = tmpScale; 
Kami dapat menyalin 
localScale ke variabel sementara karena kami tidak dapat mengubah nilai 
x -nya secara terpisah. Kemudian kami menghitung skala 
x baru berdasarkan kesehatan kumbang saat ini dan sekali lagi menetapkan nilai 
localScale ke variabel sementara.
Simpan file dan luncurkan game di Unity. Selama musuh Anda akan melihat garis-garis kesehatan.
Ketika permainan sedang berjalan, perluas salah satu objek 
Musuh (Klon) di 
Hierarki dan pilih 
HealthBar anaknya. Ubah nilainya 
Kesehatan Saat Ini dan lihat bagaimana bilah kesehatannya berubah.
Deteksi musuh dalam jangkauan
Sekarang monster kita perlu mencari tahu musuh mana yang harus dibidik. Tetapi sebelum Anda menyadari peluang ini, Anda perlu menyiapkan Monster dan Musuh.
Pilih Project Browser 
Prefabs \ Monster dan tambahkan komponen 
Circle Collider 2D ke dalam 
Inspektur .
Atur parameter 
Radius dari collider ke 
2.5 - ini akan menunjukkan radius serangan monster.
Pilih kotak centang 
Is Trigger sehingga objek melewati area ini daripada bertabrakan dengannya.
Akhirnya, di bagian atas 
Inspektur , atur 
Layer of the Monster ke 
Abaikan Raycast . Di kotak dialog, klik 
Ya, ubah anak-anak . Jika Abaikan Raycast tidak dipilih, collider akan merespons peristiwa klik mouse. Ini akan menjadi masalah karena monster memblokir acara yang ditujukan untuk objek Openspot di bawahnya.
Untuk memastikan bahwa musuh terdeteksi di area pemicu, kita perlu menambahkan collider dan body yang kaku padanya, karena Unity hanya mengirimkan event trigger ketika body yang kaku terpasang ke salah satu colliders.
Di 
Browser Proyek, pilih 
Rak itan \ Musuh . Tambahkan komponen 
2D Rigidbody dan pilih 
Kinematik untuk 
Jenis Tubuh . Ini berarti bahwa tubuh tidak akan terpengaruh oleh fisika.
Tambahkan 
Circle Collider 2D dengan 
Radius 1 . Ulangi langkah ini untuk 
Rak itan \ Musuh 2 .
Pemicu dikonfigurasikan, jadi monster akan memahami bahwa musuh berada dalam radius aksi mereka.
Kita perlu menyiapkan satu hal lagi: naskah memberi tahu monster saat musuh dihancurkan sehingga mereka tidak mengeluarkan pengecualian sambil terus menembak.
Buat skrip 
C # baru bernama 
EnemyDestructionDelegate dan tambahkan ke 
prefab Enemy dan 
Enemy2 .
Buka 
EnemyDestructionDelegate.cs di IDE dan tambahkan deklarasi delegasi berikut:
 public delegate void EnemyDelegate (GameObject enemy); public EnemyDelegate enemyDelegate; 
Di sini kita membuat 
delegate , yaitu wadah untuk fungsi yang dapat dilewatkan sebagai variabel.
Catatan : delegasi digunakan ketika satu objek game harus secara aktif memberitahukan objek perubahan game lainnya. Baca lebih lanjut tentang delegasi dalam dokumentasi Unity .
Tambahkan metode berikut:
 void OnDestroy() { if (enemyDelegate != null) { enemyDelegate(gameObject); } } 
Ketika objek game dihancurkan, Unity secara otomatis memanggil metode ini dan memeriksa delegasi untuk ketidaksetaraan 
null . Dalam kasus kami, kami menyebutnya dengan 
gameObject sebagai parameter. Ini memungkinkan semua responden yang terdaftar sebagai delegasi mengetahui bahwa musuh dihancurkan.
Simpan file dan kembali ke Unity.
Kami memberi monster izin untuk membunuh
Dan sekarang monster dapat mendeteksi musuh dalam radius aksi mereka. Tambahkan skrip 
C # baru ke 
Rakasa Rakasa dan 
beri nama 
ShootEnemies .
Buka 
ShootEnemies.cs di IDE dan tambahkan konstruksi berikut untuk mengakses 
Generics .
 using System.Collections.Generic; 
Tambahkan variabel untuk melacak semua musuh dalam jangkauan:
 public List<GameObject> enemiesInRange; 
Di dalam 
enemiesInRange kami akan menyimpan semua musuh dalam jangkauan.
Inisialisasi bidang di 
Start() .
 enemiesInRange = new List<GameObject>(); 
Pada awalnya, tidak ada musuh dalam radius aksi, jadi kami membuat daftar kosong.
Isi daftar 
enemiesInRange ! Tambahkan kode berikut ke skrip:
 
- Di OnEnemyDestroykami menghapus musuh darienemiesInRange. Ketika musuhOnTriggerEnter2Dpemicu di sekitar monster,OnTriggerEnter2D.
- Kemudian kita menambahkan musuh ke daftar enemiesInRangedan menambahkan acaraOnEnemyDestroy. Jadi kami menjamin bahwa setelah penghancuran musuhOnEnemyDestroyakan dipanggil. Kami tidak ingin monster menghabiskan amunisi pada musuh yang mati, bukan?
- Di OnTriggerExit2Dkami menghapus musuh dari daftar dan membatalkan pendaftaran delegasi. Sekarang kita tahu musuh mana yang ada dalam jangkauan.
Simpan file dan luncurkan game di Unity. Untuk memastikan semuanya berfungsi, posisikan monster, pilih dan ikuti perubahan dalam daftar 
enemiesInRange di 
enemiesInRange .
Pemilihan target
Monster sekarang tahu musuh mana yang berada dalam jangkauan. Tapi apa yang akan mereka lakukan ketika ada beberapa musuh dalam radius?
Tentu saja, mereka akan menyerang yang paling dekat dengan hati!
Buka skrip IDE 
MoveEnemy.cs dan tambahkan metode baru yang menghitung monster ini:
 public float DistanceToGoal() { float distance = 0; distance += Vector2.Distance( gameObject.transform.position, waypoints [currentWaypoint + 1].transform.position); for (int i = currentWaypoint + 1; i < waypoints.Length - 1; i++) { Vector3 startPosition = waypoints [i].transform.position; Vector3 endPosition = waypoints [i + 1].transform.position; distance += Vector2.Distance(startPosition, endPosition); } return distance; } 
Kode menghitung panjang jalur yang belum dilalui musuh. Untuk melakukan ini, ia menggunakan 
Distance , yang dihitung sebagai jarak antara dua instance dari 
Vector3 .
Kami akan menggunakan metode ini nanti untuk mencari tahu target mana yang akan diserang. Namun, sementara monster kita tidak bersenjata dan tidak berdaya, jadi pertama-tama kita akan melakukannya.
Simpan file dan kembali ke Unity untuk mulai mengatur shell Anda.
Mari kita berikan kerang monster. Banyak sekali kerang!
Seret dari Browser Proyek ke 
adegan Gambar / Objek / Bullet1 . Atur posisi pada 
z ke 
-2 - posisi pada x dan y tidak penting, karena kita mengaturnya setiap kali kita membuat instance baru proyektil ketika program dieksekusi.
Tambahkan skrip 
C # baru yang disebut 
BulletBehavior , dan kemudian di IDE tambahkan variabel berikut ke dalamnya:
 public float speed = 10; public int damage; public GameObject target; public Vector3 startPosition; public Vector3 targetPosition; private float distance; private float startTime; private GameManagerBehavior gameManager; 
speed menentukan kecepatan proyektil; 
damage jelas dari namanya.
target , 
startPosition dan 
targetPosition menentukan arah proyektil.
distance dan 
startTime melacak posisi proyektil saat ini. 
gameManager memberi hadiah kepada pemain saat dia membunuh musuh.
Tetapkan nilai-nilai variabel ini di 
Start() :
 startTime = Time.time; distance = Vector2.Distance (startPosition, targetPosition); GameObject gm = GameObject.Find("GameManager"); gameManager = gm.GetComponent<GameManagerBehavior>(); 
startTimekami menetapkan nilai waktu saat ini dan menghitung jarak antara posisi awal dan target. Juga, seperti biasa, kita dapatkan GameManagerBehavior.Untuk mengontrol pergerakan proyektil, tambahkan Update()kode berikut: 
- Kami menghitung posisi baru proyektil, menggunakan Vector3.Lerpuntuk interpolasi antara posisi awal dan akhir.
- Jika proyektil mencapai targetPosition, maka kami memeriksa untuk melihat apakah itu masih adatarget.
- Kami mendapatkan komponen HealthBartarget dan mengurangi kesehatannya dengan ukurandamageproyektil.
- Jika kesehatan musuh berkurang menjadi nol, maka kami menghancurkannya, mereproduksi efek suara dan memberi penghargaan kepada pemain untuk akurasi.
Simpan file dan kembali ke Unity.Kami membuat kerang besar
Bukankah lebih bagus jika monster itu mulai menembakkan lebih banyak peluru pada level tinggi? Untungnya, ini mudah diimplementasikan.Seret objek game Bullet1 dari Hirarki ke tab Project untuk membuat prefab proyektil. Hapus objek asli dari tempat kejadian - kita tidak lagi membutuhkannya.Gandakan cetakan Bullet1 dua kali . Beri nama salinan Bullet2 dan Bullet3 .Pilih Bullet2 . Di Inspektur, setel bidang Sprite dari komponen Sprite Renderer ke Images / Objects / Bullet2. Jadi kita akan membuat Bullet2 sedikit lebih dari Bullet1.Ulangi prosedur untuk mengubah sprite dari prefab Bullet3 ke Gambar / Objek / Bullet3 .Lebih lanjut dalam Perilaku Bullet kita akan menyesuaikan jumlah kerusakan yang disebabkan oleh peluru.Pilih prefab Bullet1 di tab Project . Di Inspektur, Anda akan melihat Bullet Behavior (Script) , di mana Anda dapat mengatur Damage menjadi 10 untuk Bullet1 , 15 untuk Bullet2 dan 20 untuk Bullet3 - atau nilai lain yang Anda suka.Catatan : Saya mengubah nilai sehingga pada tingkat yang lebih tinggi harga untuk kerusakan menjadi lebih tinggi. Ini mencegah peningkatan dari memungkinkan pemain untuk meng-upgrade monster pada poin terbaik.
Kerang pabrikan - ukuran bertambah dengan levelMengubah tingkat kerang
Tetapkan shell yang berbeda untuk berbagai level monster, sehingga monster yang lebih kuat menghancurkan musuh lebih cepat.Buka MonsterData.cs di IDE dan tambahkan ke MonsterLevelvariabel berikut: public GameObject bullet; public float fireRate; 
Jadi kami mengatur cetakan proyektil dan frekuensi api untuk setiap tingkat monster. Simpan file dan kembali ke Unity untuk menyelesaikan pengaturan monster.Pilih Rakasa Rakasa di Browser Proyek . Di Inspektur, perluas Level di komponen Monster Data (Script) . Setel Fire Rate masing - masing item menjadi 1 . Kemudian atur parameter Bullet dari Elemen 0, 1, dan 2 ke Bullet1 , Bullet2, dan Bullet3 .Level monster harus ditetapkan sebagai berikut:Kerang membunuh musuh? Ya! Mari kita buka apinya!Api terbuka
Buka ShootEnemies.cs di IDE dan tambahkan variabel berikut: private float lastShotTime; private MonsterData monsterData; 
Seperti namanya, variabel-variabel ini melacak waktu tembakan monster terakhir, serta struktur MonsterDatayang berisi informasi tentang jenis kulit monster, frekuensi api, dan sebagainya.Tetapkan nilai bidang ini di Start(): lastShotTime = Time.time; monsterData = gameObject.GetComponentInChildren<MonsterData>(); 
Di sini kita menetapkan lastShotTimenilai waktu saat ini dan mendapatkan akses ke komponen MonsterDataobjek ini.Tambahkan metode berikut untuk menerapkan pemotretan: void Shoot(Collider2D target) { GameObject bulletPrefab = monsterData.CurrentLevel.bullet;  
- Kami mendapatkan posisi awal dan target peluru. Atur posisi z sama dengan z bulletPrefab. Sebelumnya, kami menetapkan posisi cetakan proyektil di z sehingga proyektil muncul di bawah rakasa penembakan, tetapi di atas musuh.
- Kami membuat instance dari shell baru menggunakan yang bulletPrefabsesuaiMonsterLevel. TetapkanstartPositiondantargetPositionproyektil.
- Kami membuat permainan lebih menarik: ketika monster menembak, mulailah animasi dari penembakan dan mainkan suara laser.
Menyatukan semuanya
Sudah waktunya untuk menyatukan semuanya. Tentukan target dan buat monster melihatnya.Dalam skrip ShootEnemies.cs, tambahkan ke Update()kode ini: GameObject target = null;  
Pertimbangkan kode ini selangkah demi selangkah.- Tentukan tujuan monster itu. Kami mulai pada jarak maksimum yang dimungkinkan di minimalEnemyDistance. Kami berkeliling dalam siklus semua musuh dalam jangkauan dan membuat musuh menjadi target baru jika jaraknya ke cookie kurang dari yang terkecil saat ini.
- Kami memanggil Shootjika waktu yang berlalu lebih besar dari frekuensi tembakan monster dan mengaturlastShotTimenilai waktu saat ini.
- Kami menghitung sudut rotasi antara monster dan targetnya. Kami memutar monster ke sudut ini. Sekarang dia akan selalu melihat target.
Simpan file dan luncurkan game di Unity. Monster akan mulai mati-matian melindungi cookie. Kami akhirnya selesai!Ke mana harus pergi selanjutnya
Proyek yang sudah selesai dapat diunduh dari sini .Kami melakukan pekerjaan yang baik dalam tutorial ini dan sekarang kami memiliki permainan yang hebat.Berikut adalah beberapa ide untuk pengembangan proyek lebih lanjut:- Lebih banyak jenis musuh dan monster
- Rute musuh yang berbeda
- Level permainan yang berbeda
Masing-masing aspek ini akan membutuhkan perubahan minimal dan dapat membuat permainan lebih menyenangkan. Jika Anda membuat game baru berdasarkan tutorial ini, saya akan dengan senang hati memainkannya, jadi silakan bagikan tautannya.Pikiran-pikiran yang menarik tentang membuat game mengenai pertahanan menara dapat ditemukan dalam wawancara ini .