Güncelleme yöntemi ile Unity'deki FixedUpdate arasındaki fark nedir?


14

i Unity3D öğrenmeye başladım ve ben olsun karışıklık biri arasındaki farktır Update()ve FixedUpdate().

Orada Lynda Unity 2D oyun geliştirme öğreticisini takip ediyorum, eğitmen Updateyöntemi kullanıyor , oyuncunun RigidBody2D bileşeni ve Kutu çarpıştırıcısı var, Updateoyuncuyu çevirmek için yöntemi kullanıyor , ancak oynatıcıda aynı şeyi yaptığımda Updatehareket etmiyorum ama içeri FixedUpdate, her şey çalışıyor. O Unity 4.3 öğretici veriyor ve ben Unity 4.6 ders alıyorum.

Nerede kullanmalıyım Updateve FixedUpdate?

Yanıtlar:


14

Bunu bir yorum olarak yazacaktım, ama oldukça uzun soluklaştı ve bu yüzden bir cevaba dönüştürdüm.

Mevcut cevaplar çoğunlukla doğrudur, ancak bahsedilen birkaç şey yanıltıcı / yanlıştır.

Genel olarak, oyunla ilgili görevlerin çoğu devreye girer Update.

Örneğin, giriş için sorgulama yapmak istemezsiniz FixedUpdate(performans nedeniyle değil, aramalar düzgün çalışmadığı için). AI aynı tekneye düşer.

Sürekli güncellenen fizik, oynanması gereken tek görevdir FixedUpdate. Sürekli olmayan / arada bir gibi Physics.Raycast, hatta Rigidbody.AddForceait olan şeylere çağrılar Update. Bahsettiğim şey Rigidbody.AddForce, belgelerin ima ettiği şeylere aykırı görünüyor, ancak anahtar Sürekli ve Sürekli Olmayan.

Sadece sürekli fiziğin dahil olmasının çok büyük bir nedeni FixedUpdate, gerçek doğasıdır FixedUpdate. Diğer cevaplar, sabit bir güncellemede interval, but that's slightly misleading. In reality, a script is passed a time in Time.deltaTime( Time.fixedDeltaTime*) doğrudan çağrılar arasındaki gerçek zamana değil, çağrılar arasındaki simüle edilmiş zamana karşılık gelen sabit bir / * olarak çağrıldığından bahsetmiştir .

(* Time.deltaTimeVe Time.fixedDeltaTimeçağrılan aynı değeri vardır FixedUpdate[Birlik söylemek mümkün olup olmadığını, geçerli çağrı Time.deltaTimesırasında kökenli FixedUpdateve iadeler Time.fixedDeltaTime])

Doğal olarak, aynı şekilde Updatedeğişen performans nedeniyle sabit bir şekilde çağrılamaz, ikisi de olamaz FixedUpdate. Temel fark, her bir çerçeve, FixedUpdateçağrılar arasındaki doğru aralığı ortalamaya yetecek kadar sık ​​çağrılmamışsa, birden çok kez çağrılır (veya ortalamanın çok yüksek olduğu söylenmez). Bu nedir Yürütme Sipariş docs FixedUpdate birden kez bir çerçeve çağrılabilir olduğunu söyleyerek atıfta:

... FixedUpdate: FixedUpdate genellikle Güncelleme'den daha sık çağrılır. Kare hızı düşükse çerçeve başına birden çok kez çağrılabilir ve kare hızı yüksekse çerçeveler arasında hiç çağrılamayabilir ...

Bu, infaz emri ve motorun geri kalanının doğası nedeniyle Fiziği etkilemez, ancak koyduğunuz hemen hemen her şey FixedUpdateetkilenir ve sorunlara neden olur.

Örneğin, AI işlemeyi içine koyarsanız FixedUpdate, AI'nın arka arkaya birden fazla kare için güncellemeleri atlamayacağını varsaymak için hiçbir neden yoktur. Buna ek olarak, `FixedUpdate her geride kaldığında, fizik ve oyuncu girişi / hareketi gibi şeyler işlenmeden önce AI'nız tek bir karede birden çok kez güncellenir, bu da en azından işleme kaybıdır, ancak aynı zamanda zor neden olma olasılığı da yüksektir. hataları ve düzensiz davranışları izlemek için.

Eğer Birlik gibi sağlayan sabit bir aralık kullanımı, diğer yöntemlerle de bir şeyler yapmak gerekiyorsa Coroutinesve InvokeRepeating.

Ve Time.deltaTimene zaman ve ne zaman kullanılacağına dair küçük bir not :

Time.deltaTime'ın etkisini tanımlamanın en kolay yolu, bir sayıyı kare başına birimden saniyede birim olarak değiştirmesidir . Örneğin, transform.Translate(Vector3.up * 5)Güncelleme'de olduğu gibi bir komut dosyanız varsa , dönüşümü kare başına 5 metre hızında hareket ettirirsiniz . Bu, kare hızı düşükse hareket daha yavaş ve kare hızı yüksekse, hareket daha hızlı demektir.

Aynı kodu alıp olarak değiştirirseniz transform.Translate(Vector3.up * 5 * Time.deltaTime), nesne saniyede 5 metre hızla taşınır . Bu, kare hızı ne olursa olsun, nesne saniyede 5 metre hareket edecektir (ancak kare hızı ne kadar yavaşsa, nesnenin hareketi o kadar hızlıdır çünkü her X saniyede bir aynı miktarda hareket eder)

Genel olarak, hareketinizin saniyede olmasını istiyorsunuz. Bu şekilde, bilgisayarın hızı ne olursa olsun, fizik / hareketiniz aynı şekilde davranır ve daha yavaş cihazlarda garip hatalar olmaz.

Ve onu kullanmanın bir anlamı yok FixedUpdate. Yukarıda bahsettiğim için, her çağrıda aynı değeri (Sabit Güncelleme Zaman Aşımı değeri) alırsınız ve değerleriniz için hiçbir şey yapmaz. Tanımlanan Hareket / Fizik FixedUpdatezaten saniyede birimler halinde olacak, buna ihtiyacınız yok.


4

Bu Updateişleve her kare denir. Sıklığı, bilgisayarın görüntüleri ne kadar hızlı oluşturabildiğine bağlıdır. Daha yavaş bir bilgisayarda, Updatedaha hızlı olan bir bilgisayardan daha az sıklıkta çağrılır. Zamana dayalı hesaplamalar yaparsanız, bunları Time.deltaTimeson kez Updateçağrıldığından beri ne kadar sürdüğünü söyleyen normalleştirebilirsiniz (uyarılar geçerlidir).
Genellikle Updategörüntülemeyle ilgili görevleri gerçekleştirmek için kullanılır (örn. Bir kullanıcı arayüzü öğesini güncelleme)

FixedUpdateFonksiyon sabit aralıklarla denir. Görüntünün ne sıklıkta yenileneceği önemli değil, saniyede kez FixedUpdateolarak adlandırılır Genellikle oyunla ilgili görevleri gerçekleştirmek için kullanırsınız (örneğin, fiziği güncellemek gibi)1/Time.fixedDeltaTime
FixedUpdate


Bu, Time.delta zamanıyla çarpmanın bir alternatifi mi? Birini veya diğerini kullanmak için bir neden var mı?
Ben

@Ben iki farklı hedefleri var ve yaptığınız şey için doğru işlevi kullanmalısınız.
o0 '.

@Lohoris Maalesef, UpdateUpelte'i Güncelleme üzerinde kullanmak ve bunları çerçeve bağımsız hale getirmek için Time.deltaTime ile çarpmak için bir neden var mı?
Ben

@Evet evet, hassasiyet. Yavaş oluşturmaya sahip bir sistemde, Updatedaha az sıklıkta çağrılır ve simülasyonunuz bundan çok acı çeker. Simülasyon basitken fark etmeyebilirsiniz, ancak olmadığı zaman kolayca kırılır.
o0 '.

1
@ Hayır: Simülasyonunuzun kesin olmasını istiyorsanız, her seferinde rastgele daha büyük veya daha küçük olmayan çok sayıda küçük adım atmanız gerekir. Ve hayır, FixedUpdate'in bütün mesele, birçok kez çağrılması, soru sorulmaması.
o0 '.

2

Gönderen: http://unity3d.com/learn/tutorials/modules/beginner/scripting/update-and-fixedupdate

FixedUpdate'de kullanılan zaman adımı değişken değildir.

Oyununuz gecikmeye başlarsa, yakalandığında, bir güncellemede 10 saniyeden fazla fizik istemezsiniz, bu nedenle genellikle sabit aralıklarla çağrılan FixedUpdate'de yapılır.

Örneğin:

Update(float elapsedSeconds)
{
  Position += Velocity * 34.23423; //Windows Update is self-important
}
FixedUpdate(float elapsedSeconds)
{
  Position += Velocity * 0.0166; //60fps
}

Nerede:

Update(34.23423)

==

FixedUpdate(10.0)
FixedUpdate(10.0)
FixedUpdate(10.0)
//4.23423 + 5.76577 game-seconds later...
FixedUpdate(10.0)

Cevabımda bundan bahsettim, ama FixedUpdateaslında belirli bir aralıkla çağrılmıyor. Oyunun asıl doğası, FixedUpdateoyununuz gecikmeye başlarsa birden fazla fizik döngüsünü tek bir kareye sıkıştırmak ve çok hızlı giderse döngüleri atlamaktır, böylece ortalama Sabit Güncelleme Zaman Çizelgesi'ne kadar çalışır. Unity çok iş parçacıklı değildir, bu nedenle FixedUpdate çağrılarını sabit bir aralıkta garanti etmenin bir yolu olmaz (bir FixedUpdate çok uzun sürdüğünde ne olur). Olsa bile, muhtemelen hala imkansız olurdu.
Selali Adobor

Çoğu [Unity?] Kullanıcısı, Render / Update / FixedUpdate öğelerinin tek bir geri çağrı yöntemiyle çağrıldığını bilmiyor, bu yüzden kavramsallaştırdım. Emeğin için teşekkürler!
Jon

2

Updatemümkün olduğunca hızlı çağrılır. 'Time.deltaTime' değişkeni, son çağrıdan bu yana geçen gerçek süreye ayarlanır. Gecikme veya benzeri bir şey oyunu yavaşlatırsa Update, gecikme bittikten sonra yüksek bir değere sahip olmakla birlikte sadece bir kez çağrılacaktır deltaTime.

FixedUpdatedüzenli aralıklarla çağrılır. Asla 'Time.fixedDeltaTime' öğesinde belirtilen orandan daha sık çağrılmaz. Gecikme veya benzeri bir şey oyunu yavaşlatırsa FixedUpdate, oyunun yakalanmasını sağlamak için hızlı bir şekilde art arda birkaç kez çağrılacaktır. Time.deltaTimeeşit ayarlanır Time.fixedDeltaTimeönce FixedUpdateçalıştırılır, ancak bu ikisi arasında geçirmek koduna kolay bunu yapmak için sadece bir geçiştirmek olduğunu.

Genellikle, Updateinterpolable davranışlar ve FixedUpdateadım adım hesaplanması gereken veya fizik tabanlı hareket gibi olanlara bağlı davranışlar için kullanılmalıdır . Bunun Updateiçin satırlar boyunca herhangi bir döngü for(time=0;time<=deltaTime;time+=someStep)...yazıyorsanız, bunun yerine büyük olasılıkla FixedUpdate'de yapmalısınız.

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.