Game menara pertahanan semakin populer, dan ini tidak mengherankan - sedikit yang bisa dibandingkan dengan kesenangan mengamati garis pertahanan Anda sendiri yang menghancurkan musuh-musuh jahat! Dalam tutorial dua bagian ini, kita akan membuat game menara pertahanan di mesin
Unity !
Anda akan belajar bagaimana melakukan hal berikut:
- Buat gelombang musuh
- Buat mereka mengikuti titik rute
- Bangun dan tingkatkan menara, dan juga ajarkan mereka cara memecah musuh menjadi piksel kecil
Pada akhirnya, kita mendapatkan kerangka permainan, yang dapat dikembangkan lebih lanjut!
Catatan : Anda memerlukan pengetahuan Unity dasar (misalnya, Anda perlu tahu bagaimana aset dan komponen ditambahkan, apa cetakan) dan dasar-dasar C # . Untuk mempelajari semua ini, saya sarankan Anda membaca tutorial tentang Unity oleh Sean Duffy atau seri Beginning C # with Unity oleh Brian Mockley.
Saya akan bekerja di Unity untuk OS X, tetapi tutorial ini juga cocok untuk Windows.
Melalui jendela menara gading
Dalam tutorial ini, kami akan membuat game menara pertahanan tempat musuh (bug kecil) merangkak ke cookie milik Anda dan antek Anda (tentu saja, ini adalah monster!). Pemain dapat menempatkan monster di titik-titik strategis dan meningkatkannya untuk emas.
Pemain harus membunuh semua bug sampai mereka mendapatkan cookie. Setiap gelombang musuh baru menjadi semakin sulit dikalahkan. Permainan berakhir ketika Anda selamat dari semua gelombang (kemenangan!) Atau ketika lima musuh merangkak ke cookie (kalah!).
Ini adalah screenshot dari game yang sudah selesai:
Monster, satukan! Lindungi cookie!Mulai bekerja
Unduh
proyek ini
kosong , buka
zipnya , dan buka proyek
TowerDefense-Part1-Starter di Unity.
Proyek draft memiliki aset grafik dan suara, animasi siap pakai dan beberapa skrip yang berguna. Skrip tidak terkait langsung dengan game menara pertahanan, jadi saya tidak akan membicarakannya di sini. Namun, jika Anda ingin mempelajari lebih lanjut tentang membuat animasi 2D di Unity, lihat
tutorial Unity 2D ini .
Proyek ini juga mengandung cetakan, yang akan kami tambahkan nanti untuk membuat karakter. Akhirnya, ada adegan dalam proyek dengan latar belakang dan antarmuka pengguna yang disesuaikan.
Buka
GameScene yang terletak di folder
Adegan dan atur mode Game ke rasio aspek
4: 3 sehingga semua label cocok dengan latar belakang dengan benar. Dalam mode Game, Anda akan melihat yang berikut:
Karangan:- Grafik untuk proyek ini diambil dari paket Wiki Wenderlich gratis! Karya grafis lainnya dapat ditemukan di situs web gameartguppy- nya.
- Musik yang hebat diambil dari BenSound , yang memiliki soundtrack keren lainnya!
- Saya juga berterima kasih kepada Michael Jesper untuk fungsi goyangan kamera yang sangat berguna .
.
Tempat itu ditandai dengan tanda silang: lokasi monster
Monster hanya bisa ditempatkan pada titik yang ditandai dengan
x .
Untuk menambahkannya ke adegan, seret
Images \ Objects \ openspot dari
Project Browser ke jendela
Scene . Sementara posisi itu tidak penting bagi kami.
Setelah Anda memilih
Openspot dalam hierarki, klik
Tambahkan Komponen di
Inspektur dan pilih
Box Collider 2D . Di jendela Scene, Unity akan menampilkan collider persegi panjang dengan garis hijau. Kami akan menggunakan collider ini untuk mengenali klik mouse di lokasi ini.
Tambahkan komponen
Audio \ Audio Source ke
Openspot dengan cara yang sama. Untuk parameter
AudioClip komponen Sumber Audio, pilih file
tower_place yang terletak di folder
Audio dan nonaktifkan
Play On Sedarlah .
Kita perlu membuat 11 poin lagi. Meskipun ada godaan untuk mengulangi semua langkah ini, Unity memiliki solusi yang lebih baik:
Prefab !
Seret
Openspot dari
Hierarki ke folder
Rak itan di dalam
Browser Proyek . Namanya akan berubah menjadi biru dalam Hierarki, yang artinya melekat pada cetakan. Sesuatu seperti ini:
Sekarang kami memiliki cetakan prefab, kami dapat membuat salinan sebanyak yang kami suka. Cukup seret dan lepas
Openspot dari folder
Rak itan di dalam
Browser Proyek ke dalam jendela
Adegan . Ulangi ini 11 kali dan 12 objek openspot akan muncul di layar.
Sekarang gunakan
Inspektur untuk mengatur 12 objek OpenSpot ini dengan koordinat berikut:
- (X: -5.2, Y: 3.5, Z: 0)
- (X: -2.2, Y: 3.5, Z: 0)
- (X: 0,8, Y: 3,5, Z: 0)
- (X: 3,8, Y: 3,5, Z: 0)
- (X: -3,8, Y: 0,4, Z: 0)
- (X: -0,8, Y: 0,4, Z: 0)
- (X: 2.2, Y: 0.4, Z: 0)
- (X: 5.2, Y: 0.4, Z: 0)
- (X: -5.2, Y: -3.0, Z: 0)
- (X: -2.2, Y: -3.0, Z: 0)
- (X: 0,8, Y: -3,0, Z: 0)
- (X: 3,8, Y: -3,0, Z: 0)
Ketika Anda melakukan ini, pemandangannya akan terlihat seperti ini:
Kami menempatkan monster
Untuk mempermudah penempatan, ada
Rakasa Rak
Rak di folder
Rak Gudang proyek.
Monster Rakasa Siap PakaiSaat ini, itu terdiri dari objek permainan kosong dengan tiga sprite yang berbeda dan animasi penembakan sebagai anak-anak.
Setiap sprite adalah monster dengan tingkat kekuatan yang berbeda. Rak pabrikan juga berisi komponen
Sumber Audio , yang akan diluncurkan untuk memutar suara ketika monster menembakkan laser.
Sekarang kita akan membuat skrip yang akan
meng -
host Monster di
Openspot .
Di
Browser Proyek, pilih objek
Openspot di folder
Rak itan . Di
Inspektur, klik
Tambah Komponen , lalu pilih
Script Baru dan
beri nama script
PlaceMonster . Pilih
C Sharp sebagai bahasa dan klik
Buat dan Tambah . Karena kami menambahkan skrip ke prefab
Openspot , semua objek Openpot dalam adegan sekarang akan memiliki skrip ini. Hebat!
Klik dua kali pada skrip untuk membukanya di IDE. Kemudian tambahkan dua variabel:
public GameObject monsterPrefab; private GameObject monster;
Kami akan membuat instance objek yang disimpan di
monsterPrefab
untuk membuat monster, dan menyimpannya di
monster
sehingga dapat dimanipulasi selama permainan.
Satu monster per poin
Agar hanya satu monster yang dapat diletakkan pada satu titik, tambahkan metode berikut:
private bool CanPlaceMonster() { return monster == null; }
Di
CanPlaceMonster()
kita dapat memeriksa apakah variabel
monster
masih
null
. Jika demikian, maka tidak ada monster di titik itu, dan kita bisa menempatkannya.
Sekarang tambahkan kode berikut untuk menempatkan monster ketika pemain mengklik GameObject ini:
Kode ini menemukan monster ketika Anda mengklik mouse atau menyentuh layar. Bagaimana cara kerjanya?
- Unity secara otomatis memanggil
OnMouseUp
ketika seorang pemain menyentuh GameObject fisik collider. - Ketika dipanggil, metode ini menempatkan monster jika
CanPlaceMonster()
mengembalikan true
. - Kami membuat monster menggunakan metode
Instantiate
, yang membuat instance dari prefab yang diberikan dengan posisi dan rotasi yang ditentukan. Dalam hal ini, kami menyalin monsterPrefab
, memberikannya posisi GameObject saat ini dan tidak ada rotasi, mentransfer hasilnya ke GameObject
dan menyimpannya ke monster
- Pada akhirnya, kami memanggil
PlayOneShot
untuk memainkan efek suara yang melekat pada komponen AudioSource
objek.
Sekarang skrip
PlaceMonster
kami dapat memiliki monster baru, tetapi kami masih perlu menentukan cetakan.
Menggunakan Prefab Kanan
Simpan file dan kembali ke Unity.
Untuk mengatur variabel
monsterPrefab , pertama-tama pilih objek
Openspot dari folder
Rak itan di browser proyek.
Di
Inspektur, klik pada lingkaran di sebelah kanan bidang
Rakasa Rakasa komponen
PlaceMonster (Script) dan pilih
Rakasa di kotak dialog yang muncul.
Itu saja. Luncurkan adegan dan buat monster di tempat yang berbeda dengan mengklik mouse atau menyentuh layar.
Hebat! Sekarang kita bisa membuat monster. Namun, mereka terlihat seperti kekacauan aneh, karena semua sprite anak monster itu ditarik. Sekarang kita akan memperbaikinya.
Naikkan level monster
Gambar di bawah ini menunjukkan bahwa dengan peningkatan level, monster terlihat semakin menakutkan.
Manis sekali! Tetapi jika Anda mencoba mencuri cookie-nya, monster ini akan berubah menjadi seorang pembunuh.Script digunakan sebagai dasar untuk implementasi sistem level monster. Ini melacak kekuatan monster di setiap level dan, tentu saja, level monster saat ini.
Tambahkan skrip ini.
Pilih
Rak Pabrikan / Rakasa di
Browser Proyek . Tambahkan skrip
C # baru yang disebut
MonsterData . Buka skrip di IDE dan tambahkan kode berikut di
atas kelas
MonsterData
.
[System.Serializable] public class MonsterLevel { public int cost; public GameObject visualization; }
Jadi kami membuat
MonsterLevel
. Ini mengelompokkan harga (dalam emas, yang akan kami dukung di bawah) dan representasi visual dari tingkat monster.
Kami menambahkan di atas
[System.Serializable]
sehingga instance kelas dapat dimodifikasi di inspektur. Ini memungkinkan kita untuk dengan cepat mengubah semua nilai kelas Level, bahkan ketika game sedang berjalan. Ini sangat berguna untuk menyeimbangkan permainan.
Mengatur Level Monster
Dalam kasus kami, kami akan menyimpan
MonsterLevel
ditentukan di
List<T>
.
Mengapa tidak menggunakan
MonsterLevel[]
? Kita perlu indeks objek
MonsterLevel
tertentu beberapa kali. Meskipun mudah untuk menulis kode untuk ini, kita masih harus menggunakan
IndexOf()
, yang mengimplementasikan fungsionalitas
Lists
. Tidak masuk akal untuk menemukan kembali roda.
Menciptakan kembali sepeda motor biasanya merupakan ide yang buruk.Di bagian atas
MonsterData.cs, tambahkan konstruksi berikut
using
:
using System.Collections.Generic;
Ini memberi kita akses ke struktur data umum sehingga kita bisa menggunakan kelas
List<T>
dalam skrip.
Catatan : generalisasi adalah konsep C # yang kuat. Mereka memungkinkan Anda untuk menentukan struktur data tipe aman tanpa harus mematuhi tipe tersebut. Ini berguna untuk kelas kontainer seperti daftar dan set. Untuk mempelajari lebih lanjut tentang struktur generik, baca buku Pengantar C # Generik .
Sekarang tambahkan variabel berikut ke
MonsterData
untuk menahan daftar
MonsterLevel
:
public List<MonsterLevel> levels;
Berkat generalisasi, kami dapat menjamin bahwa
List
dari
level
hanya akan berisi objek
MonsterLevel
.
Simpan file dan beralih ke Unity untuk mengkonfigurasi setiap level.
Pilih
Rak itan / Rakasa di
Browser Proyek .
Inspektur sekarang menampilkan bidang
Levels dari komponen
MonsterData (Script) . Atur
ukuran ke
3 .
Selanjutnya, tetapkan
biaya untuk setiap level:
- Elemen 0 : 200
- Elemen 1 : 110
- Elemen 2 : 120
Sekarang kami menetapkan nilai bidang tampilan visual.
Perluas
Rakasa / Rakasa di peramban Proyek untuk melihat anak-anaknya. Tarik anak
Monster0 ke dalam bidang
Elemen 0 visualisasi .
Selanjutnya, atur
Elemen 1 ke
Monster1 , dan
Elemen 2 ke
Monster2 . GIF menunjukkan proses ini:
Saat Anda memilih
Rak itan / Rakasa ,
Rak itan akan terlihat seperti ini:
Setel level saat ini
Kembali ke
MonsterData.cs di IDE dan tambahkan variabel lain ke
MonsterData
.
private MonsterLevel currentLevel;
Dalam variabel private
currentLevel
kita akan menyimpan level monster saat ini.
Sekarang atur
currentLevel
dan buat itu terlihat oleh skrip lain. Tambahkan baris berikut ke
MonsterData
bersama dengan deklarasi variabel instan:
Potongan kode C # yang cukup besar, bukan? Mari kita lakukan secara berurutan:
- Atur properti variabel
currentLevel
variabel. Dengan mengatur properti, kita dapat menyebutnya seperti variabel lain: baik sebagai CurrentLevel
(di dalam kelas) atau sebagai monster.CurrentLevel
(di luar). Kita dapat mendefinisikan perilaku apa pun dalam metode pengambil atau penyetel properti, dan dengan hanya membuat pengambil, penyetel, atau keduanya, kita dapat mengontrol properti properti: baca-saja, hanya-tulis, dan tulis / baca. - Di pengambil, kami mengembalikan nilai
currentLevel
. - Di setter, kami menetapkan
currentLevel
nilai baru. Kemudian kita mendapatkan indeks level saat ini. Akhirnya, kami menggilir semua tingkatan dan mengaktifkan / menonaktifkan tampilan visual tergantung pada currentLevelIndex
. Ini bagus karena ketika currentLevel
berubah, sprite memperbarui secara otomatis. Properti adalah hal yang sangat nyaman!
Tambahkan implementasi
OnEnable
berikut:
void OnEnable() { CurrentLevel = levels[0]; }
Di sini kita mengatur
CurrentLevel
saat menempatkan. Ini memastikan bahwa hanya sprite yang diinginkan yang ditampilkan.
Catatan : penting untuk menginisialisasi properti di OnEnable
, dan bukan di OnStart
, karena kami memanggil metode ordinal saat membuat instance prefab.
OnEnable
akan dipanggil segera ketika cetakan dibuat (jika cetakan disimpan dalam keadaan diaktifkan), tetapi OnStart
tidak dipanggil sampai objek mulai berjalan sebagai bagian dari adegan.
Kami perlu memverifikasi data ini sebelum menempatkan monster, jadi kami inisialisasi ke OnEnable
.
Simpan file dan kembali ke Unity. Jalankan proyek dan tempatkan monster; mereka sekarang menampilkan sprite yang benar dari level terendah.
Peningkatan Monster
Kembali ke IDE dan tambahkan metode berikut ke
MonsterData
:
public MonsterLevel GetNextLevel() { int currentLevelIndex = levels.IndexOf (currentLevel); int maxLevelIndex = levels.Count - 1; if (currentLevelIndex < maxLevelIndex) { return levels[currentLevelIndex+1]; } else { return null; } }
Di
GetNextLevel
kita mendapatkan indeks
currentLevel
dan indeks level tertinggi; jika monster belum mencapai level maksimum, maka level berikutnya kembali. Jika tidak,
null
dikembalikan.
Anda dapat menggunakan metode ini untuk mengetahui apakah upgrade monster dimungkinkan.
Untuk menaikkan level monster, tambahkan metode berikut:
public void IncreaseLevel() { int currentLevelIndex = levels.IndexOf(currentLevel); if (currentLevelIndex < levels.Count - 1) { CurrentLevel = levels[currentLevelIndex + 1]; } }
Di sini kita mendapatkan indeks level saat ini, dan kemudian memastikan bahwa ini bukan level maksimum, memeriksa bahwa itu kurang dari level.
levels.Count - 1
. Jika demikian, maka
CurrentLevel
ke level berikutnya.
Memeriksa Fungsi Peningkatan
Simpan file dan kembali ke
PlaceMonster.cs di IDE. Tambahkan metode baru:
private bool CanUpgradeMonster() { if (monster != null) { MonsterData monsterData = monster.GetComponent<MonsterData>(); MonsterLevel nextLevel = monsterData.GetNextLevel(); if (nextLevel != null) { return true; } } return false; }
Pertama kita periksa apakah ada monster yang bisa diperbaiki dengan membandingkan variabel
monster
dengan
null
. Jika ini benar, maka kita mendapatkan level monster saat ini dari
MonsterData
-nya.
Kemudian kami memeriksa apakah level berikutnya tersedia, yaitu, apakah
GetNextLevel()
tidak mengembalikan
null
. Jika peningkatan level dimungkinkan, maka kami mengembalikan
true
; jika tidak, kembalikan
false
.
Kami menerapkan peningkatan untuk emas
Untuk mengaktifkan opsi pemutakhiran, tambahkan cabang
else if
ke
OnMouseUp
:
if (CanPlaceMonster()) {
Kami memeriksa kemungkinan peningkatan menggunakan
CanUpgradeMonster()
. Jika memungkinkan, kita mengakses komponen
GetComponent()
menggunakan
GetComponent()
dan memanggil
IncreaseLevel()
, yang meningkatkan level monster. Akhirnya, kami meluncurkan Monster
AudioSource .
Simpan file dan kembali ke Unity. Jalankan game, tempatkan dan tingkatkan
sejumlah monster (tetapi untuk sekarang).
Membayar Emas - Manajer Game
Meskipun kita bisa segera membangun dan meningkatkan monster apa pun, tetapi apakah itu akan menarik dalam game?
Mari kita lihat masalah emas. Masalah dengan pelacakan itu adalah kita harus mentransfer informasi antara objek permainan yang berbeda.
Gambar di bawah ini menunjukkan semua objek yang harus mengambil bagian dalam hal ini.
Semua objek permainan yang dipilih harus tahu berapa banyak emas yang dimiliki pemain.Untuk menyimpan data ini, kami akan menggunakan objek umum yang dapat diakses oleh objek lain.
Klik kanan pada
Hierarki dan pilih
Buat Kosong . Beri nama objek
GameManager baru.
Tambahkan skrip
C # baru yang disebut
GameManagerBehavior ke GameManager , lalu buka di IDE. Kami akan menampilkan jumlah total emas pemain di label, jadi di bagian atas file tambahkan baris berikut:
using UnityEngine.UI;
Ini akan memungkinkan kita untuk mengakses kelas UI seperti
Text
, yang digunakan untuk label. Sekarang tambahkan variabel berikut ke kelas:
public Text goldLabel;
Ini akan menyimpan tautan ke komponen
Text
digunakan untuk menampilkan jumlah emas yang dimiliki pemain.
Sekarang
GameManager
tahu tentang label, bagaimana kita menyinkronkan jumlah emas yang disimpan dalam variabel dan nilai yang ditampilkan dalam label? Kami akan membuat properti.
Tambahkan kode berikut ke
GameManagerBehavior
:
private int gold; public int Gold { get { return gold; } set { gold = value; goldLabel.GetComponent<Text>().text = "GOLD: " + gold; } }
Apakah dia tampak akrab? Kode ini mirip dengan
CurrentLevel
, yang kami atur di
Monster
. Pertama kita membuat variabel
gold
pribadi untuk menampung jumlah emas saat ini. Lalu kita atur properti
Gold
(tiba-tiba, kan?) Dan terapkan pengambil dan penyetel.
Sang pengambil hanya mengembalikan nilai
gold
. Setter lebih menarik. Selain mengatur nilai variabel, itu juga menetapkan bidang
text
untuk
goldLabel
untuk menampilkan nilai emas baru.
Bagaimana kita akan bermurah hati? Tambahkan baris berikut ke
Start()
untuk memberi pemain
1000 emas, atau kurang jika Anda menyesal atas uang itu:
Gold = 1000;
Menetapkan objek label ke skrip
Simpan file dan kembali ke Unity. Di
Hirarki, pilih
GameManager . Di
Inspektur, klik pada lingkaran di sebelah kanan
Label Emas . Di kotak dialog
Select Text , pilih tab
Scene dan pilih
GoldLabel .
Jalankan adegan dan label akan menampilkan
Emas: 1000 .
Memeriksa "dompet" pemain
Buka skrip
PlaceMonster.cs di IDE dan tambahkan variabel instance berikut:
private GameManagerBehavior gameManager;
Kami akan menggunakan
gameManager
untuk mengakses komponen
GameManagerBehavior
dari objek
GameManagerBehavior
di layar. Untuk menentukannya, tambahkan yang berikut ke
Start()
:
gameManager = GameObject.Find("GameManager").GetComponent<GameManagerBehavior>();
Kami mendapatkan GameObject bernama GameManager menggunakan fungsi
GameObject.Find()
, yang mengembalikan objek game pertama yang ditemukan dengan nama itu. Kemudian kita mendapatkan komponen
GameManagerBehavior
dan menyimpannya untuk masa depan.
Catatan : Anda bisa melakukan ini dengan menyetel bidang di editor Unity atau dengan menambahkan metode statis ke GameManager
yang mengembalikan instance singleton dari mana kita bisa mendapatkan GameManagerBehavior
.
Namun, dalam blok kode yang ditunjukkan di atas ada kuda hitam: metode Find
, yang bekerja lebih lambat selama eksekusi aplikasi; tetapi nyaman dan dapat digunakan dalam jumlah sedang.
Ambil uangku!
Kami belum mengurangi emas, jadi kami akan menambahkan baris ini
dua kali ke
OnMouseUp()
, menggantikan masing-masing komentar
// TODO:
:
gameManager.Gold -= monster.GetComponent<MonsterData>().CurrentLevel.cost;
Simpan file dan kembali ke Unity, perbarui beberapa monster dan lihat pembaruan nilai Gold. Sekarang kami mengurangi emas, tetapi pemain dapat membangun monster selama mereka memiliki cukup ruang; mereka hanya meminjam uang.
Kredit tak terbatas? Hebat! Tapi kita tidak bisa membiarkannya. Pemain harus bisa bertaruh monster sementara dia memiliki cukup emas.Cek Emas untuk Monster
Beralih di IDE ke
PlaceMonster.cs dan ganti konten
CanPlaceMonster()
berikut:
int cost = monsterPrefab.GetComponent<MonsterData>().levels[0].cost; return monster == null && gameManager.Gold >= cost;
Kami
MonsterData
penempatan monster dari
levels
di
MonsterData
-nya. Lalu kita periksa
monster
bukan
null
, dan itu
gameManager.Gold
lebih dari harga ini.
Tugas untuk Anda: tambahkan secara independen ke
CanUpgradeMonster()
centang apakah pemain memiliki cukup emas.
Solusi di dalamGanti baris:
return true;
tentang ini:
return gameManager.Gold >= nextLevel.cost;
Ini akan memeriksa apakah pemain memiliki lebih banyak
Emas daripada harga upgrade.
Simpan dan jalankan adegan di Unity. Sekarang cobalah cara menambahkan monster tanpa batas!
Sekarang kita hanya dapat membangun sejumlah monster.Kebijakan menara: musuh, gelombang, dan titik arah
Inilah saatnya untuk "membuka jalan" bagi musuh-musuh kita. Musuh muncul di titik pertama rute, pindah ke yang berikutnya dan ulangi prosesnya hingga mencapai cookie.
Anda dapat membuat musuh bergerak seperti ini:
- Atur jalan yang akan diikuti musuh
- Pindahkan musuh di sepanjang jalan
- Putar musuh sehingga dia melihat ke depan
Membuat jalan dari titik arah
Klik kanan pada
Hierarchy dan pilih
Create Empty untuk membuat objek game baru yang kosong. Beri nama
Jalan dan posisikan di
(0, 0, 0) .
Sekarang klik kanan pada
Road in the
Hierarchy dan buat objek game kosong lainnya sebagai anak Road. Beri nama
Waypoint0 dan letakkan di titik
(-12, 2, 0) - dari sini musuh akan memulai gerakan mereka.
Demikian pula, buat lima titik rute lagi dengan nama dan posisi berikut:
- Waypoint1: (X: 7, Y: 2, Z: 0)
- Waypoint2: (X: 7, Y: -1, Z: 0)
- Waypoint3: (X: -7.3, Y: -1, Z: 0)
- Waypoint4: (X: -7.3, Y: -4.5, Z: 0)
- Waypoint5: (X: 7, Y: -4.5, Z: 0)
Tangkapan layar di bawah ini menunjukkan titik rute dan jalur yang dihasilkan.
Membuat musuh
Sekarang buat beberapa musuh sehingga mereka bisa bergerak di sepanjang jalan. Ada prefab
Musuh di folder
Rak itan . Posisinya adalah
(-20, 0, 0) , jadi instance baru akan dibuat di luar layar.
Dalam semua hal lain, ini dikonfigurasi hampir dengan cara yang sama seperti Rakasa Rakasa, memiliki
AudioSource
dan anak
Sprite
, dan kita dapat memutar sprite ini di masa depan tanpa memutar bar kesehatan.
Kami menggerakkan musuh di sepanjang jalan
Tambahkan skrip
C # baru yang disebut
MoveEnemy ke
prefab \ prefab Musuh . Buka skrip di IDE dan tambahkan variabel berikut:
[HideInInspector] public GameObject[] waypoints; private int currentWaypoint = 0; private float lastWaypointSwitchTime; public float speed = 1.0f;
Di
waypoints
, salinan titik rute disimpan dalam array, dan baris
[HideIn inspector ]
atas
waypoints
memastikan bahwa kami tidak dapat secara tidak sengaja mengubah bidang ini di
Inspektur , tetapi masih akan memiliki akses ke sana dari skrip lain.
currentWaypoint
melacak dari mana rute musuh dari pada saat ini, dan
lastWaypointSwitchTime
menyimpan waktu ketika musuh melewatinya. Selain itu, kami menyimpan
speed
musuh.
Tambahkan baris ini ke
Start()
:
lastWaypointSwitchTime = Time.time;
Jadi kami menginisialisasi
lastWaypointSwitchTime
dengan nilai waktu saat ini.
Agar musuh bergerak di sepanjang rute, tambahkan kode berikut ke
Update()
:
Mari kita menganalisis kode langkah demi langkah:
- Dari berbagai titik rute, kami mendapatkan posisi awal dan akhir dari segmen rute saat ini.
- Kami menghitung waktu yang diperlukan untuk mencakup seluruh jarak menggunakan rumus waktu = jarak / kecepatan , dan kemudian menentukan waktu saat ini pada rute. Menggunakan
Vector2.Lerp
, kami menginterpolasi posisi musuh saat ini antara segmen awal dan akhir yang tepat. - Periksa apakah musuh telah mencapai
endPosition
. Jika ya, maka kami memproses dua skenario yang mungkin:
- Musuh belum mencapai titik terakhir rute, jadi tambah nilai
currentWaypoint
dan perbarui lastWaypointSwitchTime
. Nanti kita akan menambahkan kode untuk mengubah musuh sehingga dia melihat ke arah gerakannya. - Musuh telah mencapai titik terakhir dari rute, lalu kita hancurkan dan mulai efek suara. Nanti kita akan menambahkan kode yang mengurangi
health
pemain.
Simpan file dan kembali ke Unity.
Kami memberi tahu musuh tentang arah gerakan
Dalam kondisi saat ini, musuh tidak mengetahui urutan titik rute.
Pilih
Jalan di
Hirarki dan tambahkan skrip
C # baru yang disebut
SpawnEnemy . Buka di IDE dan tambahkan variabel berikut:
public GameObject[] waypoints;
Kami akan menggunakan
waypoints
untuk menyimpan referensi ke titik lewat dalam adegan dalam urutan yang diinginkan.
Simpan file dan kembali ke Unity. Pilih
Road di
Hierarchy dan atur
Size of the
Waypoints array menjadi
6 .
Seret setiap anak Jalan ke dalam bidang dengan menempelkan
Waypoint0 di
Elemen 0 ,
Waypoint1 di
Elemen 1, dan seterusnya.
Sekarang kami memiliki array yang berisi titik rute dalam urutan yang benar - ingat, musuh tidak pernah mundur, mereka terus-menerus berjuang untuk mendapatkan hadiah yang manis.
Periksa cara kerjanya
Buka
SpawnEnemy di IDE dan tambahkan variabel berikut:
public GameObject testEnemyPrefab;
Ini akan menyimpan referensi ke
testEnemyPrefab
Musuh di
testEnemyPrefab
.
Untuk membuat musuh saat menjalankan skrip, tambahkan kode berikut ke
Start()
:
Instantiate(testEnemyPrefab).GetComponent<MoveEnemy>().waypoints = waypoints;
Jadi kami akan membuat salinan cetakan baru yang disimpan di
testEnemy
dan memberinya rute.
Simpan file dan kembali ke Unity. Pilih objek
Jalan di
Hirarki dan pilih prefab
Musuh untuk parameter
Uji Musuh .
Luncurkan proyek dan lihat bagaimana musuh bergerak di sepanjang jalan (di GIF, untuk kejelasan, kecepatannya meningkat 20 kali).Melihat bahwa dia tidak selalu melihat ke mana dia pergi? Ini lucu, tapi kami mencoba membuat game profesional. Oleh karena itu, di bagian kedua tutorial kami akan mengajarkan musuh untuk berharap.Ke mana harus pergi selanjutnya?
Kami telah melakukan banyak hal dan dengan cepat bergerak menuju pembuatan game pertahanan menara kami sendiri.Pemain dapat membuat sejumlah monster, dan musuh berlari di sepanjang jalan, menuju cookie kami. Pemain memiliki emas dan mereka dapat meningkatkan monster.Unduh hasil akhirnya dari sini .Pada bagian kedua, kita akan mempertimbangkan penciptaan gelombang besar musuh dan kehancuran mereka. Sampai ketemu lagi!