Oyuncu nesneleriyle uğraşırken ne zaman addForce'a karşı hız kullanmalıyım?


18

Birlik çerçevesinde bu iki yöntem hakkında kafam karıştı. Her ikisi de oyuncu nesnesini hareket ettirir, durdurur, yön değiştirir vb.



@ Byte56 her iki soru da farklı şeyler soruyor
Robert

1
Farklı, ama ilgili. Bu yüzden sadece bağlantılı ve kopya değiller. Sağdaki bağlantılı sütunda gösterilir.
MichaelHouse

Yanıtlar:


13

Sen kullanmayı tercih ediyorum velocity(örneğin bir kurşun) sabit bir hızda nesneyi hareket ettirmek ve AddForce()(örneğin bir uzay gemisi itici için) hareketini ekleyin. Ayrıca iki tür "hareket" olduğuna dikkat edin; kuvvet ve dürtü. Bir uzay gemisi pervanesi için dürtü kullanırsınız.


4
Bir uzay gemisi pervanesi için neden dürtüleri tercih ettiğinizi açıklayabilir misiniz? Silah darbeleri gibi şeylerden dolayı anlık momentum değişiklikleri yerine, zaman içinde kademeli hızlanma uygularsanız, bu ideal olmayan bir uyum olabilir. Zaman penceresine
uygulandığında

@DMGregory Evet, eklemek istediğiniz kuvvet türüne bağlıdır. Anlık bir enerji patlaması olan uzay gemisi pervanesi örneğimde, dürtü doğru seçimdir.
trojanfoe

2
Bir tutum jetinin kısa bir ateşlenmesi mi yoksa bir ana motorun sürekli yanması mı demek istediniz belli değildi ("itici" bazen bilimkurguda biraz genel olarak kullanılıyor), bu yüzden birinin denemesine izin vermem gerektiğini düşündüm bir roket güçlendirici için dürtü kullanarak. ;)
DMGregory

@DMGregory Gerçekten; uzay teknolojisi terminolojim büyük ölçüde filmlere dayanıyor :)
trojanfoe

@trojanfoe Git KSP oyna. Hemen şimdi.
user253751

21

Zaten kabul edilmiş bir cevap olmasına rağmen, ele almaya değer bazı ek ayrıntılar olduğunu düşünüyorum.

Hızı Kullanma

Hız ayarladığınızda, o nesnenin hareketini etkileyebilecek diğer her şeyi kesinlikle geçersiz kılıyorsunuz. Bazı durumlarda bu, bir merminin ilk hızını, atıldığı anda, örneğin trojanfoe örneğinde olduğu gibi ayarlamak gibi arzu edilir. Dikkatli olun, çünkü yanlış durumlarda kullanıldığında sorunlara neden olabilir:

  • Birden fazla kaynak / komut dosyası, aynı Rigidbody hızını doğrudan ayarlayarak (yani. body.velocity = foo) Değiştirmeye çalışırsa , hangisi en son kazanırsa ve diğerleri sıfır etkiye sahiptir. Bu, güncelleme hatalarının sırasına yol açabilir, özellikle de varlıkların yavaşça durmasına veya düşmesine neden olabilir (çünkü yerçekiminden kaynaklanan aşağı doğru hızlanma birikmeden önce geçersiz kılınır)

  • Her karede hız ayarlıyorsanız, diğer nesnelerle çarpışma biraz garip olabilir. Sanki nesneniz sonsuz torka sahip bir motor tarafından tahrik ediliyor - bir etki üzerinde ne kadar hız kaybederse kaybederse, bir sonraki fizik adımında en yüksek hıza geri dönüyor ve hızı etkiden uzaklaşmıyor . Bu, çarpıştığınız nesneleri başlatmanıza veya küçük nesnelerin büyük nesneleri olması gerektiği gibi çok daha kolay bir şekilde itmesine veya uzaklaşmak / boyunca saptırmak yerine statik engeller boyunca yavaşça kaymasına neden olabilir.

Bu etkilerin her ikisi de bazen istenebilir. Örneğin, Kinect oyunları yaparken ve oyuncunun sanal avatarının uzuvlarının fizik sahnesiyle etkileşime girmesini istediğimde, genellikle bu bedenleri doğrudan hız ayarını kullanarak hareket ettiririm. Oyuncunun gerçek eli bilinen bir yerde olduğu ve bu sanal nesneyle çarpışmadan yavaşlamadığı için, sanal ellerinin aynı hizada kalması için aynı şeyi yapması gerekiyor, bu nedenle bu durumda diğer tüm fizik etkilerini geçersiz kılmak istiyoruz . oraya götür.

AddForce ve Arkadaşları

Buna karşın AddForce ve benzeri yardımcı fonksiyonlar, fizik dünyasında olan her şeyle işbirliği yapmak için yapılır. Birden fazla kaynak / komut dosyası bir Rigidbody'e AddForce ise, nesnenin hareketinde net bir değişiklik oluşturmak için tüm bu efektler birlikte eklenir (bu, nasıl hesaplandığına bağlı olarak, siparişten bağımsız da olabilir). Bu, bir komut dosyasının diğer bazı fizik efektlerini tamamen durdurmasını önlemeye yardımcı olur.

AddForce , farklı şeyler için yararlı olan isteğe bağlı ForceMode parametresini belirterek dört çeşittir :

ForceMode       |   Use
-----------------------------------------------------------------------
Force (default) |   Accelerate an object over 1 time step, based on its mass.
                |   Units: Newtons = kg * m/s^2
                |
Acceleration    |   Accelerate an object over 1 time step, ignoring its mass. (like gravity)
                |   Units: m/s^2
                |
Impulse         |   Instantaneously propel an object, based on its mass
                |   Units: N * s = kg * m/s
                |
VelocityChange  |   Instantaneously propel an object, ignoring its mass
                |   (like body.velocity = foo, except multiple scripts can stack)
                |   Units:  m/s

Bir araba sürüşü veya bir roket yakma veya yerçekimi iyi bir çekme gibi zaman içinde sürekli bir itme (örn. Her FixedUpdate uyguladığınız bir şey) modellemeye çalışıyorsanız, Kuvvet veya Hızlanma istersiniz. (Ağır nesnelerin daha yavaş hızlanmasını isteyip istemediğinize bağlı olarak)

Bir mermi ateşlemek, bir patlamadan geri tepmek veya bir bariyeri sıçramak gibi ani ve keskin bir hareket değişikliği modelliyorsanız, Impulse veya VelocityChange'i daha çok istersiniz.

AddForce kullanmak daha fazla fiziksel gerçekçilik elde etmenize yardımcı olur, ancak davranışlarınızın fiziği üzerinde düşünmek için daha fazla zaman harcamanızı gerektirebilir. Örneğin, vücudunuzun hedef hıza kadar sınırlı bir hızlanmaya sahip olmasını istiyorsanız, çarpışmalara her karenin hızını ayarlamaktan daha gerçekçi tepki vermesi için, muhtemelen bu yardımcı işleve benzer bir hesaplama isteyeceksiniz:

public static void AccelerateTo(this Rigidbody body, Vector3 targetVelocity, float maxAccel)
{
    Vector3 deltaV = targetVelocity - body.velocity;
    Vector3 accel = deltaV/Time.deltaTime;

    if(accel.sqrMagnitude > maxAccel * maxAccel)
        accel = accel.normalized * maxAccel;

    body.AddForce(accel, ForceMode.Acceleration);
}

Tüm bu "yardımcı fonksiyonlar" olarak adlandırmamın nedeni, teknik olarak aynı uçları elde edebilmenizdir:

 body.velocity += suitablyCalculatedDeltaV;

( Bence . Unity'nin PhysX / Box2D tabanlı fizik, AddForce aracılığıyla arabellek değişikliklerini ayrı ayrı çözüyor, ancak bunun belirgin sonuçlarını görmedim)

Günün sonunda, bu işlevlerin bize gerçekten kazandırdığı şey niyetin netliğidir . Kademeli bir kuvvet uygulamak istediğimde, deltaV'ımı Time.deltaTime ile çarpmayı ve kütleye bölmeyi hatırlamama gerek yok, sadece ForceMode.Force istediğimi söylüyorum ve doğru ve tutarlı bir şekilde işleniyor. Ve ben ya da bir başkası kodumu daha sonra yinelemeye geldiğinde, bunu anlamak için zaman ve kütle hesaplamalarının kodunu çözmeye gerek kalmadan ne demek istediğimi hemen anlar.


6

Trojanfoe'un cevabına ek olarak , Angry Birds vs Car Racing. Bu yöntemlerin ( AddForceve velocitysırasıyla) iki ana ve farklı örneği . Örneğin, Angry Birds'de mermi yörüngesini kendi başınıza ayarlamak zorunda kalacağınız için hız kullanımı biraz daha zordur, örneğin,

Angry Birds'de AddForce kullandığımda,

_birdRigidbody.AddForce(new Vector2(5,5));

Hızı kullanırken o zaman yörüngeyi kullanarak

x = v*t*Cos(theta) y = v*t*Sin(theta) - 0.5 * g * t *t

Ya da bunun gibi bir şey.

Araba Yarışı oyununda iken, Angry Birds yani Shoot ve hepsi gibi hızı her zaman kontrol etmek zorunda kalacaksınız. Yani bu senaryoda tanıtıcı velocitydaha yararlıdır AddForce.

Umarım anlarsın. En azından biraz.


1
AngryBirds örneğinizde, sapan serbest bırakıldığında, bir zaman penceresi üzerinde etkisini taklit eden varsayılan ForceMode.Force yerine anlık momentum değişikliği (örn. Impulse veya VelocityChange) kullanılmalıdır. Her iki yaklaşımdan da eşdeğer davranış elde etmek için sayıları ayarlayabilirsiniz, ancak sabit zaman adımınızı değiştirirseniz, kuvvet çözümünün farklı bir çıkışı olacaktır (çünkü kuvveti daha uzun veya daha kısa bir zaman aralığında entegre ettiği için) çünkü sadece salınma anını temsil eder.
DMGregory

0

Rigidbody Velocity ve Rigidbody Addforce, Unity 3D'de iki kafa karıştırıcı işlevdir ve genellikle yeni başlayanlar farklarını anlayamazlar. Bu makalede, RigidBody.velocity ve RigidBody.addforce arasındaki farkı tartışacağız.

Her iki durumda da, Addforce ya da speed fonksiyonu olsun, bunları açıklamak için kuvvet terimini kullanacağız.

Rigidbody.velocity kullanırken, bu durumda, nesnemize kuvvet ekliyoruz, ancak bu kuvvet, nesneyi ancak kuvvet uygulamaya devam etmedikçe ve devam edene kadar hareket ettirecektir.

Örneğin

body.velocity = yeni Vector3 (0,0,5);

Diyelim ki z konumuna 5f eklediniz ve W tuşuna bastığınızda bu kuvvet eklenecektir. Yani W tuşuna bastığınızda, nesne anında 5 hızında başlayacaktır. Bir arabada bu işlevi kullanarak kuvvet ekliyorsanız, bu araba 5 hızında başlayacaktır.

body.velocity = yeni Vector3 (0,0,200);

Değeri 200 olarak değiştirmenize izin verirseniz ve sonra kaydettikten sonra W düğmesine basın. Araba, gerçek dünyada mümkün olmayan başlangıçtan 200 hızında çalışmaya başlayacaktır.

Şimdi Rigidbody.addforce hakkında konuşuyorsanız

Araba örneğimize devam ederek. 200 kuvvetini arabaya eklerseniz

body.addforce (0,0,200);

W tuşuna basarsak Araba 200 hızında hareket etmeye başlamaz, ancak yavaştan başlar ve ardından Drag'ın değerine göre hızlarını arttırır ve durur.

Rigidbody.addforce yavaş başlar ve sonra hızlanır, tıpkı ağır bir masayı sürüklediğiniz gibi, önce o masayı itmeye başlayacaksınız, masa sadece pozisyonundan biraz hareket edecek, ancak o masayı itmeye devam ederseniz hareket etmeye başlayacak ve Bu masayı terk ederseniz, yüzeye bağlı olarak biraz mesafe kat edecektir ve bu aynı katı cisimdir.

Oyuncu zıplaması gibi anında tepki vermek için nesnenizi hareket ettirmek istediğiniz Rigidbody.velocity'yi kullanabilirsiniz ve bu kuvvetin sonucu atlamadan hemen sonra ortadan kaybolacak ve yavaş başlangıç ​​ve ardından sürekli hareket gibi ihtiyaç duyduğunuz yerlerde Rigidbody.addforce'u kullanabilirsiniz. roket. Atlamada Rigidbody.addforce kullanırsanız, Oyuncu / Nesne bir süre uzayda kalır ve sonra tekrar yere döner.

(kaynak)


En azından yazınızı Stack Exchange yanıtı biçimine uyarlamaya çalışmalısınız :)
Vaillancourt
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.