Unity, güncelleme yöntemini almak için neden yansımayı kullanıyor?


12

Neden erişim amacıyla Birlik kullanım yansıma yapar MonoBehaviourgibi mesaj yöntemlerle Awake, Update, Start, ...?

Yansımayı kullanmak yavaş olmaz mıydı? Neden diğer yaklaşımlardan faydalanmıyor Template Method? Yöntemleri MonoBehaviourtemel sınıfta soyut olarak tanımlayabilir ve alt sınıfları uygulamaya zorlayabilir.

Yanıtlar:


20

Öyle değil

Güncelleme nasıl çağrılır

Hayır, Unity her çağırdığında sihirli bir yöntem bulmak için System.Reflection'ı kullanmaz.

Bunun yerine, belirli bir tipteki bir MonoBehaviour'a ilk kez erişildiğinde, temeldeki komut dosyası, tanımlanmış herhangi bir sihirli yöntemi olup olmadığı ve bu bilgilerin önbelleğe alındığı komut dosyası çalıştırma zamanı (Mono veya IL2CPP) aracılığıyla denetlenir. Bir MonoBehaviour belirli bir yönteme sahipse, uygun bir listeye eklenir, örneğin bir komut dosyasının Güncelleme yöntemi tanımlıysa, her karede güncellenmesi gereken komut dosyaları listesine eklenir.

Oyun sırasında Birlik sadece bu listeleri tekrarlar ve ondan yöntemler yürütür - bu kadar basit. Ayrıca, bu nedenle Güncelleme yönteminizin herkese açık veya özel olması önemli değildir.

Gelince nedenlerle bu şekilde yapılır, ben size (okuyucu) bakınız ölçüde edeceğiz DMGregory cevabı iki rakip şeylerin bir denge kaynar aşağı:

  1. Verim iyileştirmesi
  2. Yeni geliştirici kullanım kolaylığı

Yeni bir geliştirici sadece Çalışmasını istiyor ve "bunu olay sistemine nasıl bağlarım?" ancak yine de minimum ek yük ile hızlı çalışmalıdır.

Çözüm, muhtemelen bu iki kısıtlama içinde elde edilebilecek en iyisidir . Ya da en azından, Unity dev ekibinin o zaman en iyi şekilde gelebilmesi. Asla bilemeyebiliriz.


2
tl; dr aynı süreç, farklı, daha hızlı API. Ama neden OP tarafından sorulduğu gibi farklı bir yöntem seçmediler?
wondra

10
Biz sade eski "kötü tasarım" nedeni olasılığını inkar etmemeliyiz. C # kaynak kodunun yayınlanmasından sonra kullanıcılar tonlarca hata ve açıklanamayan tasarım kararları buldu. Bazı gamedevler nihayet yıllarca mücadele ettikleri beklenmedik davranışları anlayabildi.
Egzersiz

Teknikler bir yana, yeni gelenlerin öğrendiği ilk şeylerden biridir, bu yüzden eklemek veya atlamak kolay olmalıdır.
Nikaas

6
Bu tasarımın tarihi nedenleri de olabilir. Birlik kendi komut dosyası dili ile başladı, daha sonra yavaş yavaş C # lehine aşamalı olarak kaldılar. Biraz aldatmak istese bile aynı kalıpları kullanmaya devam etmek istedikleri doğaldır.
Philipp

3
Sanırım "Birlik bu yolla neyi başarabiliyor?" hepsi uygulanması gereken soyut bir kamu yöntemlerinin bir koleksiyonuna göre avantajı nedir? "Birlik geliştiricileri ne düşünüyordu?" ancak "bu yaklaşım motor kullanıcıları için neden yararlıdır?"
DMGregory

10

Yöntemleri basitçe MonoBehaviour temel sınıfında soyut olarak tanımlayabilir ve alt sınıfları uygulamaya zorlayabilir.

Unity'nin kullandığı sistemin avantajlarından biri, 60'tan fazla olan her MonoBehaviour mesajını uygulamak zorunda olmamanızdır .

Genellikle bu yöntemlerden birine veya birkaçına ihtiyacımız var. Bazıları 2D / 3D fiziğe özgü, bazıları kameralara veya parçacık sistemlerine özgü olduğundan, herhangi bir komut dosyasının hepsine ihtiyaç duyması pek olası değildir.

İhtiyaç duymadığımız mesajları bırakarak, çalışma zamanına açıkça "bu nesne üzerinde OnCollisionStay2D'yi çağırmayı bile rahatsız etmeyin - buna ihtiyacım yok" sinyalini verebiliriz.

Bu önemli bir verimlilik kazancı olabilir. Şimdi motor, sahnemdeki her karede özel güncelleme mantığına ihtiyaç duyan ~ 20 nesneye ve tüm sahneyi oluşturan veya sadece fizik olaylarına yanıt veren ~ 200 nesneye değil, Güncelleme'yi çağırmak için kısa listeyi filtreleyebilir.


Sadece bir soru ... bildiğim kadarıyla (kişisel olarak değil), hepsi Güncelleme yöntemiyle bir komut dosyası kullanan binlerce GameObjects varsa, önemli performans etkileriniz var. Alternatif olarak, listeleri kullanmak ve bir yönetici komut dosyasında yalnızca bir Güncelleme yöntemiyle yineleme yapmak , bu da önemli ölçüde daha yüksek performansa sahip gibi görünüyor. Bu hala geçerli mi, yoksa zaten değişti mi? - Hiçbir şey değişmezse, Unity'nin bunu yapmasının performans konusunda hiçbir yere yakın olmadığı anlamına gelir.
Savaş

4
@Açıkladığınız şey, Draco18s'in 2015'ten alıntı yaptığı bağlantıyla tutarlıdır ve bunun hala doğru olduğundan şüphelenirim. Bu binlerce nesnede Güncelleme yöntemini tanımsız bırakabilmek, bu optimizasyonun çalışmasına izin veren şeydir. Her MonoBehaviour, alıntıladığım sorunun bölümünde açıklandığı gibi soyut bir temel sınıf aracılığıyla tanımlanan bir Güncelleme yöntemine sahip olsaydı, güncelleme çağrılarımızı sadece yöneticinin liste yinelemesiyle sınırlama yeteneğimiz olmazdı. Bu soru-cevap kısmının "Unity'nin yaklaşımı en uygun mu?" ancak sadece mevcut yaklaşımın nasıl faydalı olabileceği.
DMGregory

Ah, anlıyorum, bu gerçekten mantıklı. Cevap için teşekkürler!
Savaş

@Battle Hala doğru. Unity'nin yaptığı şey alternatiflerden daha performanslı olsa da, normal bir işlev çağrısından daha fazla yükü vardır.
Draco18s artık

@ Draco18s - Evet. Projelerim için uzun zaman önce bu optimizasyonla ilgilenen bir UpdateManager uyguladım. Sadece hala gerekli / yararlı olduğunu doğrulamak istedim.
Savaş
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.