Unity'de C# Olayları
Coddy'nin Unity Journey'sinin Unity'de Oyun Mimarisi bölümünün bir parçası. Ders 10 / 50.
Puan değiştiğinde bunu önemseyen birkaç şey vardır: puan metni, bir ses, bir başarı. ScoreKeeper bunların her birini çağırırsa her biri için bir alana ihtiyaç duyar ve her yeni özellikte onu düzenlemek gerekir. Bir olay bunu tersine çevirir: ScoreKeeper değişikliği duyurur ve ilgilenenler abone olur. C# dilinden event ve Action kavramlarını biliyorsun. Unity'de yayıncı ve dinleyicileri bileşenlerdir; genellikle farklı GameObject'ler üzerindedirler:
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, HUD'un metninde
public ScoreKeeper keeper;
public TMP_Text label;
void Start()
{
keeper.OnScoreChanged += ShowScore;
}
void ShowScore(int score)
{
label.text = "Score: " + score;
}Action<int>, her dinleyicinin tek bir int alan bir metot olduğu anlamına gelir; burada bu, yeni puandır. Invoke, abone olunan her metodu abonelik sırasına göre çağırır. Hiç dinleyici yoksa olay null olur; bu nedenle düz bir OnScoreChanged(score) bir NullReferenceException hatasına yol açar, ?. ise çağrıyı atlar. event anahtar sözcüğü diğer betiklerin yalnızca += ve -= kullanmasına izin verir: ScoreLabel içinde keeper.OnScoreChanged(5) veya keeper.OnScoreChanged = null derlenmez.
ScoreKeeper'ın etiket için bir alanı yoktur ve etiketin varlığından haberi de yoktur. Bir kombo sayacı veya ses oynatıcı da aynı şekilde abone olur ve ScoreKeeper olduğu gibi kalır; HUD içermeyen bir test sahnesi de hata vermeden çalışır. Bir dinleyici, buradaki gibi bir Inspector referansı aracılığıyla ya da GetComponent veya bir singleton gibi bildiğin başka bir yolla yayıncıyı bulur. Nesneler yok edildiğinde bir dinleyiciyi -= ile kaldırmak önem kazanır; bu bir sonraki dersin konusu.
Görev
KolayDövüşçünün kombosu, Space tuşuna her basışta artar ve bir vuruş olmadan comboWindow (1) saniye geçince 0'a sıfırlanır. Şu anda Fighter.cs, kombo metnini ve alevin boyutunu kendisi ayarlıyor; bu yüzden her biri için bir alana ihtiyaç duyuyor. Bunu bir olay kullanarak değiştir:
Fighter.csiçinde, komboyu (bir int) iletenOnComboChangedadlı bir public olay tanımla. Kombo her değiştiğinde (0'a sıfırlanması da dahil) yeni komboyla olayı tetikle ve kimse dinlemiyorken bir vuruşun hataya neden olmadığından emin ol.- Fighter'ın
comboTextveflamealanlarını ve bunları kullanan satırları sil: Fighter, HUD hakkında hiçbir şey bilmez. ComboText.csveComboFlame.csiçinde,ShowveGrowmetotlarınıStart()içinde dövüşçünün olayına abone et. İkisinde de sahneye bağlanmış birfighteralanı var.
Oyna'ya bas, Space ile kum torbasına birkaç kez vur, bir saniye bekle ve ardından Kontrol Et'e bas.
Kendin dene
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;
}
}
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Unity'de Oyun Mimarisi bölümündeki tüm dersler
1Hiyerarşiler Değil, Bileşenler
Küçük BileşenlerTemel Bir Düşman BetiğiSoyut BileşenlerBirlikte Çalışan BileşenlerÖzet: Modüler Taret4Serileştirilmiş Veriler
Serileştirilebilir SınıflarInspector'da ListelerInspector'da Enum'larÖzet: Ganimet Tablosu7Durum Makineleri
Sınıflar Olarak DurumlarBir Durum MakinesiGeçişlerDüşmanların Yapay ZekâsıTekrar: Kapı Durumları10Proje: Arena Hayatta Kalma
KahramanDüşman Türleri5ScriptableObjects
Veri VarlıklarıSilah İstatistikleriPaylaşılan AyarlarVeri Olarak DalgalarTekrar: Eşya Veritabanı8Yeniden Kullanılabilir Kod
Genişletme MetotlarıGeneric SingletonGeneric YardımcılarTekrar: FindNearest3Olaylar
Unity'de C# OlaylarıOnEnable'da Abone OlmaUnityEvent AlanlarıOlaylar Arayüzü YönlendirirTekrar: Başarım Açılır Penceresi