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.Atan2
untuk menentukan sudut dalam radian di mana diarahkan arah baru (titik nol di sebelah kanan). 180 / Mathf.PI
hasilnya dengan 180 / Mathf.PI
, mengubah sudut menjadi derajat. - Akhirnya, ia mendapatkan anak Sprite dan memutar derajat
rotationAngle
sumbu. 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
timeInterval
dari timeBetweenWaves
. Jika tidak, kami memeriksa apakah timeInterval
dari spawnInterval
wave. Bagaimanapun, kami memeriksa bahwa kami belum menciptakan semua musuh di gelombang ini. - Jika perlu, buat musuh, buat instance dari
enemyPrefab
. Juga tingkatkan nilai enemiesSpawned
. - 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
CameraShake
untuk 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
gameOver
menjadi true
dan mulai animasi gameOver
. - 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
OnEnemyDestroy
kami menghapus musuh dari enemiesInRange
. Ketika musuh OnTriggerEnter2D
pemicu di sekitar monster, OnTriggerEnter2D
. - Kemudian kita menambahkan musuh ke daftar
enemiesInRange
dan menambahkan acara OnEnemyDestroy
. Jadi kami menjamin bahwa setelah penghancuran musuh OnEnemyDestroy
akan dipanggil. Kami tidak ingin monster menghabiskan amunisi pada musuh yang mati, bukan? - Di
OnTriggerExit2D
kami 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>();
startTime
kami 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.Lerp
untuk interpolasi antara posisi awal dan akhir. - Jika proyektil mencapai
targetPosition
, maka kami memeriksa untuk melihat apakah itu masih ada target
. - Kami mendapatkan komponen
HealthBar
target dan mengurangi kesehatannya dengan ukuran damage
proyektil. - 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 MonsterLevel
variabel 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 MonsterData
yang 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 lastShotTime
nilai waktu saat ini dan mendapatkan akses ke komponen MonsterData
objek 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
bulletPrefab
sesuai MonsterLevel
. Tetapkan startPosition
dan targetPosition
proyektil. - 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
Shoot
jika waktu yang berlalu lebih besar dari frekuensi tembakan monster dan mengatur lastShotTime
nilai 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 .