MENAMBAHKAN MUSUH DAN MENGEMBANGKAN GRAFIS GAME 3D
4.5 RAYTRACING - APA ITU RAYCASTING?
2. Masuk ke Tag & Layers Manager menggunakan salah satu dari tiga metode yang terdaftar sebelumnya dan tambahkan dua layer baru: Abaikan Lampu dan Abaikan Kamera
3. Pilih salah satu kubus dan tambahkan ke layer Ignore Lights. Pilih kubus lainnya dan tambahkan ke layer Abaikan Kamera.
4. Pilih Directional Light di scene, dan di properti Culling Mask, batalkan pilihan layer Ignore Lights. Perhatikan bahwa sekarang hanya satu kubus yang menyala. Yang lain telah diabaikan karena layernya.
5. Pilih Main Camera dan hapus layer Ignore Cameras dari properti Culling Mask. Jalankan scene dan perhatikan bahwa hanya satu kubus yang tidak diterangi yang muncul. Yang lain telah diabaikan oleh kamera.
Menggunakan perintah ScreenPointToRay untuk pemotretan
Anda akan menerapkan pemotretan dengan memproyeksikan sinar yang dimulai dari kamera dan meluas ke depan melalui pusat tampilan. Memproyeksikan sinar melalui pusat tampilan kamera adalah kasus khusus dari tindakan yang disebut sebagai memetik mouse.
Definisi Memilih mouse adalah tindakan memilih tempat dalam scene 3D langsung di bawah kursor mouse. Unity menyediakan metode ScreenPointToRay() untuk melakukan tindakan ini. Gambar 3.2 mengilustrasikan apa yang terjadi. Metode ini menciptakan sinar yang dimulai pada kamera dan diproyeksikan pada sudut yang melewati koordinat layar yang diberikan. Biasanya koordinat posisi mouse digunakan untuk memilih mouse, tetapi untuk pemotretan orang pertama digunakan bagian tengah layar. Setelah Anda memiliki sinar, itu dapat diteruskan ke metode Physics.Raycast() untuk melakukan raycasting menggunakan sinar itu.
Gambar 4.13 ScreenPointToRay() memproyeksikan sinar dari kamera melalui koordinat layar yang diberikan.
Mari kita menulis beberapa kode yang menggunakan metode yang baru saja kita bahas.
Di Unity buat skrip C# baru, lampirkan skrip itu ke kamera (bukan objek pemutar), lalu tulis kode dari daftar berikutnya di dalamnya.
Gambar 4.14 Skrip RayShooter untuk dilampirkan ke kamera
Anda harus mencatat beberapa hal dalam daftar kode ini. Pertama, komponen kamera diambil di Start(), seperti CharacterController di bab sebelumnya. Kemudian sisa kode dimasukkan ke dalam Update() karena perlu memeriksa mouse berulang kali, bukan hanya satu kali. Metode Input.GetMouseButtonDown() mengembalikan nilai true atau false tergantung pada apakah mouse telah diklik, jadi menempatkan perintah tersebut dalam kondisi berarti kode terlampir hanya berjalan ketika mouse telah diklik. Anda ingin menembak
ketika player mengklik mouse; maka cek kondisional tombol mouse. Sebuah vektor dibuat untuk menentukan koordinat layar untuk sinar (ingat bahwa vektor adalah beberapa angka terkait yang disimpan bersama). Nilai pixelWidth dan pixelHeight kamera memberi Anda ukuran layar, jadi membagi nilai tersebut menjadi dua memberi Anda bagian tengah layar.
Meskipun koordinat layar adalah 2D, dengan hanya komponen horizontal dan vertikal dan tanpa kedalaman, Vector3 dibuat karena ScreenPointToRay() memerlukan tipe data tersebut (mungkin karena penghitungan sinar melibatkan aritmatika pada vektor 3D).
ScreenPointToRay() dipanggil dengan set koordinat ini, menghasilkan objek Ray (objek kode, yaitu, bukan objek game; keduanya terkadang membingungkan).
Sinar tersebut kemudian diteruskan ke metode Raycast(), tetapi itu bukan satu- satunya objek yang dilewatkan. Ada juga struktur data RaycastHit; RaycastHit adalah kumpulan informasi tentang perpotongan sinar, termasuk di mana perpotongan itu terjadi dan objek apa yang berpotongan. Sintaks C# out memastikan bahwa struktur data yang dimanipulasi di dalam perintah adalah objek yang sama yang ada di luar perintah, sebagai lawan dari objek yang menjadi salinan terpisah dalam cakupan fungsi yang berbeda.
Akhirnya kode memanggil metode Physics.Raycast(). Metode ini memeriksa persimpangan dengan sinar yang diberikan, mengisi data tentang persimpangan, dan mengembalikan true jika sinar itu mengenai sesuatu. Karena nilai Boolean dikembalikan, metode ini dapat dimasukkan ke dalam pemeriksaan bersyarat, sama seperti Anda menggunakan Input.GetMouseButtonDown() sebelumnya.
Untuk saat ini kode memancarkan pesan konsol untuk menunjukkan saat terjadi persimpangan. Pesan konsol ini menampilkan koordinat 3D dari titik di mana sinar itu mengenai (nilai XYZ yang kita bahas di bab 2). Tetapi mungkin sulit untuk memvisualisasikan di mana tepatnya sinar itu mengenai; demikian pula, sulit untuk mengetahui di mana pusat layar berada (yaitu, di mana sinar menembus). Mari tambahkan indikator visual untuk mengatasi kedua masalah tersebut.
Menambahkan indikator visual untuk membidik dan memukul
Langkah kita selanjutnya adalah menambahkan dua jenis indikator visual: titik bidik di tengah layar, dan tanda di tempat di mana sinar itu mengenai. Untuk Sniper pertama yang terakhir biasanya lubang peluru, tetapi untuk saat ini Anda akan meletakkan bola kosong di tempat (dan menggunakan coroutine untuk menghapus bola setelah satu detik).
Gambar 4.15 Memotret berulang kali setelah menambahkan indikator visual untuk membidik dan memukul
Coroutine adalah cara khusus Unity untuk menangani tugas yang dijalankan secara bertahap dari waktu ke waktu, berbeda dengan cara sebagian besar fungsi membuat program menu nggu hingga selesai. Pertama mari kita tambahkan indikator untuk menandai di mana sinar itu mengenai. Listing 3.2 menunjukkan script setelah melakukan penambahan ini. Berlari di sekitar lokasi syuting; cukup menyenangkan melihat indikator bola!
Gambar 4.16 Skrip RayShooter dengan indikator bola ditambahkan
Metode baru adalah SphereIndicator(), ditambah modifikasi satu baris dalam metode Update() yang ada. Metode ini membuat bola pada suatu titik dalam scene dan kemudian menghapus bola itu sedetik kemudian. Memanggil SphereIndicator() dari kode raycasting memastikan bahwa akan ada indikator visual yang menunjukkan dengan tepat di mana sinar itu mengenai. Fungsi ini didefinisikan dengan IEnumerator, dan tipe itu terikat dengan konsep coroutine.
Secara teknis, coroutine tidak asinkron (operasi asinkron tidak menghentikan sisa kode untuk berjalan; pikirkan untuk mengunduh gambar dalam skrip situs web), tetapi melalui penggunaan enumerator yang cerdas, Unity membuat coroutine berperilaku mirip dengan fungsi asinkron . Saus rahasia dalam coroutine adalah kata kunci hasil; kata kunci itu menyebabkan coroutine berhenti sementara, mengembalikan aliran program dan mengambil lagi dari titik itu di bingkai berikutnya. Dengan cara ini, coroutine tampaknya berjalan di latar belakang program, melalui siklus berulang yang berjalan di tengah jalan dan kemudian kembali ke program lainnya.
Sesuai dengan namanya, StartCoroutine() menggerakkan coroutine. Setelah coroutine dimulai, coroutine terus berjalan sampai fungsi selesai; itu hanya berhenti di sepanjang jalan.
Perhatikan poin halus namun signifikan bahwa metode yang diteruskan ke StartCoroutine() memiliki serangkaian tanda kurung yang mengikuti namanya: sintaks ini berarti Anda memanggil fungsi itu, bukan meneruskan namanya. Fungsi yang dipanggil berjalan hingga mencapai perintah hasil, di mana fungsi berhenti.
SphereIndicator() membuat bola pada titik tertentu, berhenti sejenak untuk pernyataan hasil, lalu menghancurkan bola setelah coroutine dilanjutkan. Panjang jeda
dikendalikan oleh nilai yang dikembalikan pada hasil. Beberapa jenis nilai pengembalian yang berbeda berfungsi di coroutine, tetapi yang paling mudah adalah mengembalikan jangka waktu tertentu untuk menunggu. Mengembalikan WaitForSeconds(1) menyebabkan coroutine berhenti sejenak selama satu detik. Buat bola, jeda selama satu detik, lalu hancurkan bola: urutan itu menyiapkan indikator visual sementara.
Gambar 4.17 Daftar Indikator visual untuk membidik
Metode baru lainnya telah ditambahkan ke kelas RayShooter, yang disebut OnGUI().
Unity hadir dengan sistem antarmuka pengguna (UI) dasar dan yang lebih canggih; karena sistem dasar memiliki banyak keterbatasan, kami akan membangun UI lanjutan yang lebih fleksibel di bab mendatang, tetapi untuk saat ini menampilkan titik di tengah layar menggunakan UI dasar jauh lebih mudah. Sama seperti Start() dan Update(), setiap MonoBehaviour secara otomatis merespons metode OnGUI(). Fungsi itu menjalankan setiap bingkai tepat setelah scene 3D dirender, menghasilkan semua yang digambar selama OnGUI() muncul di atas scene 3D (bayangkan stiker diterapkan pada lukisan lanskap).
Definisi Render adalah tindakan komputer menggambar piksel scene 3D. Meskipun scene ditentukan menggunakan koordinat XYZ, tampilan sebenarnya pada monitor Anda adalah kisi 2D piksel berwarna. Jadi untuk menampilkan scene 3D, komputer perlu menghitung warna semua piksel dalam kisi 2D; menjalankan algoritma itu disebut sebagai rendering.
Di dalam OnGUI() kode mendefinisikan koordinat 2D untuk tampilan (digeser sedikit untuk memperhitungkan ukuran label) dan kemudian memanggil GUI.Label(). Metode itu menampilkan label teks; karena string yang diteruskan ke label adalah tanda bintang (*), Anda berakhir dengan karakter yang ditampilkan di tengah layar. Sekarang jauh lebih mudah untuk membidik di game FPS kami yang baru lahir! Selalu ingat bahwa Anda dapat menekan Esc untuk membuka kunci kursor mouse. Saat kursor mouse terkunci, tidak mungkin mengklik tombol Play dan menghentikan permainan.