Event C# di Unity
Termasuk bagian Arsitektur Game di Unity dalam perjalanan Unity di Coddy. Pelajaran 12 dari 64.
Saat skor berubah, ada beberapa hal yang perlu mengetahuinya: teks skor, suara, pencapaian. Jika ScoreKeeper memanggil masing-masing hal tersebut, ScoreKeeper memerlukan field untuk setiap hal, dan setiap fitur baru berarti ScoreKeeper harus diedit. Sebuah event membalikkan alur ini: ScoreKeeper mengumumkan perubahan, lalu siapa pun yang membutuhkannya berlangganan.
Dua kata C# membuat ini berfungsi. Action<int> adalah tipe method yang menerima satu int dan tidak mengembalikan apa pun. Sebuah event dengan tipe tersebut adalah daftar method seperti itu: kode lain menambahkan method-nya dengan +=, lalu pemiliknya memanggil semuanya dengan Invoke. Dalam C# biasa:
using System;
class Alarm
{
public event Action<int> Rang;
public void Ring(int hour)
{
Rang?.Invoke(hour);
}
}
class Sleeper
{
public void WakeUp(int hour)
{
Console.WriteLine("Up at " + hour);
}
}
// di tempat lain
Alarm alarm = new Alarm();
Sleeper sleeper = new Sleeper();
alarm.Rang += sleeper.WakeUp;
alarm.Ring(7); // Bangun pukul 7Di Unity, publisher dan listener-nya adalah komponen, biasanya pada GameObject yang berbeda:
using System;
using UnityEngine;
public class ScoreKeeper : MonoBehaviour
{
public event Action<int> OnScoreChanged;
private int score;
public void AddPoints(int points)
{
score += points;
OnScoreChanged?.Invoke(score);
}
}// ScoreLabel.cs, pada teks HUD
public ScoreKeeper keeper;
public TMP_Text label;
void Start()
{
keeper.OnScoreChanged += ShowScore;
}
void ShowScore(int score)
{
label.text = "Score: " + score;
}Action<int> berarti setiap listener adalah method yang menerima satu int, dalam contoh ini skor baru. Invoke memanggil setiap method yang berlangganan, sesuai urutan mereka berlangganan. Jika tidak ada listener, event bernilai null, jadi OnScoreChanged(score) biasa akan memunculkan NullReferenceException, sedangkan ?. melewatkan pemanggilan. Kata kunci event membatasi skrip lain agar hanya bisa menggunakan += dan -=: di ScoreLabel, keeper.OnScoreChanged(5) atau keeper.OnScoreChanged = null tidak bisa di-compile.
ScoreKeeper tidak memiliki field untuk label dan tidak tahu bahwa label itu ada. Penghitung combo atau pemutar suara berlangganan dengan cara yang sama, dan ScoreKeeper tetap seperti semula, sementara scene pengujian tanpa HUD berjalan tanpa error. Listener menemukan publisher melalui referensi Inspector, seperti di sini, atau dengan cara apa pun yang kamu ketahui, seperti GetComponent atau singleton. Menghapus listener dengan -= penting setelah object dihancurkan, dan itu akan dibahas di pelajaran berikutnya.
Tantangan
MudahBuat petarung menampilkan combo-nya.
- Di
Fighter.cs, tambahkanusing System;danpublic event Action<int> OnComboChanged;. - Ganti baris yang menggunakan
comboTextdanflamedenganOnComboChanged?.Invoke(combo);, lalu hapus kedua field. - Di dalam
Start()padaComboTextdanComboFlame, tulisfighter.OnComboChanged += Show;dan+= Grow;.
Tekan tombol “Main” dan tekan Space beberapa kali: combo bertambah, lalu dihapus. Lalu tekan tombol “Periksa”.
Coba sendiri
using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;
public class Fighter : MonoBehaviour
{
public float comboWindow = 1f;
public TMP_Text comboText;
public Transform flame;
private int combo;
private float sinceHit;
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
combo++;
sinceHit = 0f;
comboText.text = "Combo x" + combo;
flame.localScale = Vector3.one * (0.5f + 0.25f * combo);
}
else if (combo > 0)
{
sinceHit += Time.deltaTime;
if (sinceHit > comboWindow)
{
combo = 0;
comboText.text = "";
flame.localScale = Vector3.one * 0.5f;
}
}
}
}
Semua pelajaran di Arsitektur Game di Unity
1Komponen, Bukan Hierarki
Komponen KecilSkrip Dasar MusuhKomponen AbstrakKomponen yang Bekerja BersamaRangkuman: Turret ModularRangkuman: Meriam Kembar4Data yang Diserialisasi
Class yang Dapat DiserialisasiList di InspectorEnum di InspectorRangkuman: Tabel LootRangkuman: Acak Loot2Antarmuka di Unity
IDamageableAntarmuka dan TryGetComponentGetComponentsRingkasan: Tombol InteractRingkasan: Terdekat dalam Jangkauan5ScriptableObjects
Aset DataStatistik SenjataPengaturan BersamaSelamatkan AnginGelombang sebagai DataRekap: database ItemBeli dari Toko8Kode yang Dapat Digunakan Kembali
Extension methodSingleton GenerikHelper GenerikUlasan: FindNearestLatihan sendiri: Playground Unity