Unity’de Ragdoll Nasıl Kullanılır? (Ragdoll Physics)

Unity’de Ragdoll Nasıl Kullanılır? (Ragdoll Physics)

15 Mayıs 2020 0 Yazar: Ahmet Güler

Merhaba, bir önceki yazımda Unity‘de ekran çözünürlüğünü nasıl ayarlayabileceğimizi öğrenmiştik.Böylece Unity‘de proje geliştiren kişilerin en büyük sorularından biri olan, her çözünürlükte projemizin aynı görünmesini nasıl sağlayabileceğimizi öğrenmiştik.Bugünkü dersimizde ise, Unity’de Ragdoll, türkçe anlamıyla bez bebek sisteminin kullanımını öğreneceğiz.Çok basit anlatımla Ragdoll, modellerin odun gibi durmamasını sağlıyor.

Ragdoll, özellikle fizik unsurlarının ön planda olduğu birçok projede kullanılıyor.Unity içerisinde geliştiricilerin işini kolaylaştırmak için bir Ragdoll Manager aracı bulunuyor.Böylelikle hızlı bir şekilde ragdoll fiziğini vermek istediğiniz nesneye uygulayabiliyorsunuz.Bugünkü dersimizde bu aracın nasıl kullanılacağını göstereceğim.İlerde ki derslerde ise, bir nesneye manuel olarak nasıl ragdoll ekleyebileceğimizi göstereceğim.Şimdi vakit kaybetmeden Unity‘de yeni bir proje oluşturalım ve dersimize başlayalım.

Sahnemizi hazırlamaya başlayalım.

Bu projede kullanacağımız senaryoyu önce bir inceleyelim.Ragdoll fiziğini daha iyi anlamak için, uyguladığımız nesneye bir kuvvet uygulamamız gerekiyor.Örneğin bu bir yerçekimi kuvveti de olabilir.Yada nesneye doğrudan uyguladığımız bir kuvvet de olabilir.Böylece nesnenin eklem hareketlerini daha iyi görebiliyoruz.Bunları anlatmamda ki sebep ise, projede kullanacağımız senaryonun bir top atışı üzerine olmasındandır.Mermi içinde bir insan modeli kullanacağız.

Böylece az önce bahsettiğim fizik kuvvetini, topun içerisine yerleştirdiğimiz insan modeline uygulayarak ragdoll fiziğini daha iyi görmüş olacağız.Şimdi sahnemize bir Plane nesnesi ekleyerek projemize başlayalım.Eklediğimiz bu plane nesnesi, bizim zeminimizi oluşturacak.Daha sonra topumuzu sahnemize eklememiz gerekiyor.Bu topu, Unity‘de bulunan Cylinder ile de yapabilirsiniz.Ancak ben bir 3D model kullanmayı tercih ettim.

Unity-Ragdoll-Nasıl-Kullanılır-How-to-do-Easy-Unity3D-Ragdoll-Physics

Top nesnemizi sahnemize ekledikten sonra, ragdoll fiziğini uygulayacağımız bir nesneye ihtiyacımız var.Bunun için ben, yine internetten bulduğum bir 3D model kullanacağım.Eğer bu yazıyı okuyorsanız büyük ihtimal sizinde elinizde bir 3D model bulunuyorduk.Eğer yoksa, internetten kolaylıkla bulabileceğiniz bir model kullanmanızı tavsiye ederim.Tabi seçtiğiniz modelin eklemleri birbirinden bağımsız olarak kontrol edilebilmesi gerekiyor.Yani tek parça bir model işimize yaramayacaktır.

Evet böylece ragdoll fiziğini daha iyi anlamış ve öğrenmiş olursunuz.Sahnemizi hazırladık.Şimdi yazımızın asıl konusuna geçebiliriz.Öncelikle ragdoll fiziğini uygulayacağımız nesnemizin, Hierarchy penceresinde bulunan tüm elemanlarını düzenlemenizi öneririm.Aşağıdaki görselden de anlayacağınız üzere, bu şekilde bir hiyerarşik düzenleme yapmanız sizin işinizi oldukça kolaylaştıracaktır.Böylece ilerde bir değişiklikliğe gitmeniz gerekirse, kafanız karışmadan işinizi çözmüş olacaksınız.

Unity-Ragdoll-Nasıl-Kullanılır-How-to-do-Easy-Unity3D-Ragdoll-Physics

Nesnemizi ragdoll fiziğini nasıl uygulayacağız?

Şimdi ragdoll fiziğini modelimize uygulamaya gelelim.Öncelikle Ragdoll Manager aracını açmamız gerekiyor.Bunun için Hierarchy penceresinde (GameObject menüsünden de erişilebilir.) sırasıyla, 3D Object > Ragdoll yolunu izliyoruz.Karşımıza bu şekilde bir pencere açılacaktır.Dediğim gibi bu pencere, bizim nesnelerimize manuel olarak eklememiz gereken bileşenleri otomatik olarak ekliyor.Dikkat ederseniz, RagdollBuilder adında bir C# Script dosyası yer alıyor.

Şimdi bu pencerede bulunan ve bizi ilgilendiren elemanların ne olduklarına bir bakalım.

  1. Pelvis : Bu bölüme, modelimizin ebeveyn nesnesini ekliyoruz.Türkçe karşılığı ise, leğen kemiğidir.
  2. Left Hips :  Bu bölüme, modelimizin sol kalça nesnesini ekliyoruz.Sol kalça derken, sol kalçadan itibaren yani komple sol bacağı ekliyoruz.
  3. Left Knee : Bu bölüme, modelimizin sol diz nesnesini ekliyoruz.
  4. LeftFoot : Bu bölüme, modelimizin  sol ayak nesnesini ekliyoruz.
  5. Right Hips :  Bu bölüme, modelimizin sağ kalça nesnesini ekliyoruz.Yine az öncede belirtiğim üzere, sağ kalçadan itibaren yani komple sağ bacağı ekliyoruz.
  6. Right Knee : Bu bölüme, modelimizin sağ diz nesnesini ekliyoruz.
  7. Right Foot : Bu bölüme, modelimizin  sağ ayak nesnesini ekliyoruz.
  8. Left Arm : Bu bölüme, modelimizin  sol kol nesnesini ekliyoruz.
  9. Left Elbow : Bu bölüme, modelimizin  sol dirsek nesnesini ekliyoruz.
  10. Right Arm : Bu bölüme, modelimizin sağ kol nesnesini ekliyoruz.
  11. Right Elbow : Bu bölüme, modelimizin sağ dirsek nesnesini ekliyoruz.
  12. Middle Spine : Bu bölüme, modelimizin orta omurgasını yani bel nesnesini ekliyoruz.
  13. Head : Bu bölüme, modelimizin kafa nesnesini ekliyoruz.
  14. Total Mass : Bu bölüme, nesnemiz için olmasını istediğimiz ağırlığını yazıyoruz.

Evet pencerede bulunan yerlere, modelimiz üzerinde bulunan hangi bölümlerin eklenmesi gerektiğini öğrendiğimize göre artık tek tek eklemeye başlayabiliriz.Hierarchy penceresindeki elemanları tutup sürükleyerek ilgili bölümlere bırakıyoruz.Yazımın başında da dediğim gibi eğer modelimizin bölümlerini hiyerarşik bir düzene getirdiysek, hiç zorlanmadan ve karıştırmadan kolay bir şekilde bu penceredeki bölümleri dolduracaksınız.

Unity-Ragdoll-Nasıl-Kullanılır-How-to-do-Easy-Unity3D-Ragdoll-Physics

Create butonuna bastıktan sonra Ragdoll Manager aracı, bizim yerimize gerekli bileşenleri pencere üzerine eklemiş olduğumuz nesnelere otomatik olarak ekliyor.Bu da doğrusu bizim zamanımızı oldukça kısaltıyor.Eklediği bileşenler ise Box Collider, Capsule Collider, Sphere Collider, Rigidbody ve Character Joint bileşenidir.Bu bileşenleri bazılarını yazılarımdan biliyorsunuz.Bilmediklerinizi ise daha sonraki yazılarımda anlatacağım.

Ancak yüzeysel olarak üzerinden geçmem gerekiyor.Yukarda yazdığım Collider bileşenlerinden sadece bir tanesi nesneye ekleniyor.Örneğin Kafa bölgesine, Sphere Collider bileşeni ekleniyor.Bel ve üst gövdeye ise, Box Collider bileşeni ekleniyor.Capsule Collider bileşeni ise, kalan bölgelere ekleniyor.Rigidbody ve Character Joint bileşenleri ise, tüm bölümlere ekleniyor.Çünkü bu bölümler ragdoll fiziğini oluşturan asıl unsurlardır.Evet ragdoll fiziğini modelimize ekledik.Scene penceresine baktığımız zaman modelin bölümlerini açık bir şekilde görebiliyoruz.

Unity-Ragdoll-Nasıl-Kullanılır-How-to-do-Easy-Unity3D-Ragdoll-Physics

Evet ragdoll fiziğini modelimize uyguladık.Şimdi projemizi başlattığımız zaman modelimizin yere yapıştığını göreceksiniz.Burada aslında yazının amacını tamamlamış bulunmaktayız.Ancak ben her yazıda olduğu gibi bu yazıda da ekstra mekanikler eklemek istiyorum.Çünkü bu yazıdaki senaryo, toptan bir insan fırlatmaktı.Şimdi bunu gerçekleştirmek için kodlarımızı yazmaya başlayalım.

Ragdoll fiziğini kontrol edelim.

Dediğim gibi, projeyi başlattıktan sonra ragdoll fiziğini uyguladığımız nesne hemen yere düşecektir.Bunun önüne geçmek ve istediğimiz zaman bu fiziği kullanmak için bir kaç kod yazmamız gerekiyor.Şimdi bunun için yeni bir C# Script dosyası oluşturuyoruz ve editör yardımı ile açıyoruz.

public Rigidbody Fizik;
public BoxCollider KutuCarpistirici;
public Collider[] TumCarpistiricilar;
public Rigidbody[] TumFizikler;
public float Zaman;
public bool Atesle;

Öncelikle bize lazım olan değişkenleri oluşturmakla başlıyoruz.İlk satırda bir Rigidbody değişkeni oluşturuyoruz.Bu değişken ile ebeveyn nesnemizin Rigidbody bileşenini kontrol edeceğiz.İkinci satırda bir BoxCollider değişkeni oluşturuyoruz.Yine bu değişkeni, ebeveyn nesnemizin BoxCollider bileşenini kontrol etmek için oluşturduk.

Üçüncü satırda bir Collider dizisi oluşturuyoruz.Bu diziye, ebeveyn (parent) nesnemizin altında yer alan çocuk (child) nesnelerinin içerisindeki tüm Collider bileşenlerini bulup ekleyeceğiz.Tüm dedim, çünkü türüne bakılmaksınız, Collider olması yeterli olacaktır.Dördüncü satırda yine bir dizi oluşturuyoruz.Bu sefer Rigidbody dizisi oluşturuyoruz.

Bu dizi değişkenimizede , ebeveyn (parent) nesnemizin altında yer alan çocuk (child) nesnelerinin içerisindeki Rigidbody bileşenlerini bulup ekleyeceğiz.Bunları neden tespit ettiğimizi yeri gelince anlatacağım.Beşinci satırda float türünde bir değişken oluşturuyoruz.Bu değişken ile topu ateşleme zamanını kontrol edeceğiz.Son satırda ise, bool türünde bir değişken oluşturuyoruz.Bu değişkenle ise, topu ateşlemeyi kontrol edeceğiz.

Fizik = GetComponent<Rigidbody>();
KutuCarpistirici = GetComponent<BoxCollider>();
TumCarpistiricilar = GetComponentsInChildren<Collider>();
TumFizikler = GetComponentsInChildren<Rigidbody>();
Zaman = 0;
Atesle = false;

Şimdi start() fonksiyonumuzun içerisine bu kodları yazıyoruz.İlk satırda değişkenimize, script dosyamızı eklediğimiz nesnenin Rigidbody bileşenini tanımlıyoruz.İkinci satırda değişkenimize, yine script dosyamızı eklediğimiz nesnenin BoxCollider bileşenini tanımlıyoruz.Üçüncü ve dördüncü satırlarda ise değişkenlerimize, GetComponentsInChildren fonksiyonunu kullanarak aradığımız bileşenleri ekliyoruz.

Bu fonksiyon yardımı ile, hiyeraşik olarak en altta yer alan nesneye bile ulaşabiliyoruz.Böylece eksiksiz olarak oluşturduğumuz dizilere, Collider ve Rigidbody bileşenlerini eklemiş oluyoruz.Beşinci satırda değişkenimizin değerini sıfıra “0” eşitliyoruz.Böylece projeyi başlattığımız zaman, ateşlemek için kullanacağımız zamanda sıfırlanmış olacaktır.Son satırda ise, bool türündeki değişkenimizin değerini false olarak belirliyoruz.

public void RagDollKontrol (bool Durum) {
   foreach (Collider carpistiricilar in TumCarpistiricilar) {
      carpistiricilar.enabled = Durum;
   }
   foreach (Rigidbody fizikler in TumFizikler) { 
      fizikler.isKinematic = !Durum; 
   }
}

Şimdi yeni bir fonksiyonu oluşturuyoruz.Bu fonksiyon ile modelimiz için oluşturduğumuz ragdoll fiziğini kontrol edeceğiz.Bu fonksiyonu parametreli olarak oluşturduk.Çünkü dinamik olarak içerisindeki bileşenlerin durumlarını kontrol etmemiz gerekiyor.Bu yüzden bool türünde bir parametre yer alıyor.Evet fonksiyonu gayet basit tuttum.İçerisinde sadece iki döngü kullanıyoruz.Ancak bu döngüler oldukça önem arz ediyor.

İkinci satıra bakacak olursak, bir foreach döngüsü görüyoruz.Özellikle dizilerde bu döngü işimizi oldukça kolaylaştırıyor.Bu döngü yardımı ile, “TumCarpistiricilar” dizimizin içerisinde yer alan Collider bileşenlerine erişiyoruz.Üçüncü satırda, dizideki tüm Collider bileşenlerinin aktifliğini kontrol ediyoruz.Bunu yapmak içinde bool türündeki parametremizi kullanıyoruz.

Beşinci satırda, yeni bir foreach döngüsü yazıyoruz.Bu döngüde ise, “TumFizikler” dizimizin içerisinde yer alan Rigidbody bileşenlerine erişiyoruz.Altıncı satırda, dizideki tüm Rigidbody bileşenlerinde yer alan “isKinematic” özelliğinin aktifliğini kontrol ediyoruz.Bunu yapmak içinde yine bool türündeki parametremiz bizim yardımımıza konuşuyor.

if (Input.GetKeyDown(KeyCode.Space)) {
   Atesle = true;
   Fizik.isKinematic = false;
}

Şimdi bu kodları update() fonksiyonumuzun içerisine yazıyoruz.İlk satırda yeni bir koşul oluşturuyoruz.Bu koşul ile, topumuzu ateşleyecağiz.Eğer klavyeden space (boşuk) tuşuna basarsak, koşulumuz aktif oluyor.İkinci satırda, bool türündeki değişkenimizin değerini true olarak değiştiriyoruz.Üçüncü satırda ise, “Fizik” değişkenimizin isKinematic özelliğini false olarak değiştiriyoruz.

if (Atesle) {
   Zaman += Time.deltaTime;
   if (Zaman >= 1f) {
      Fizik.AddForce(Vector3.forward * 1000f, ForceMode.Impulse);
      RagDollKontrol (true);
      Zaman = 0;
      Atesle = false;
   }
}

Yine update() fonksiyonundan devam ediyoruz.Yeni bir koşul oluşturuyoruz.Bu koşul ile, topumuzu ateşleme zamanını başlatacağız ve ardından ateşleyeceğiz.Neden iki koşul ile bunu yapıyoruz derseniz, eğer tek bir koşul kullanmış olsaydık GetKeyDown fonksiyonu nedeni ile, tuşa basılı tutmak zorunda kalacaktık.Bunun önüne geçmek için, ilk koşulda bool değişkenimizin değerini değiştirdik.İkincisinde ise, ateşlemeyi başlattık.

İkinci satırda değişkenimizin değerini, Time.deltaTime fonksiyonu ile arttırıyoruz.Üçüncü satırda, bir koşul daha oluşturuyoruz.Bu koşulla ise, zamanlayıcımızı kontrol ediyoruz.Yani bir “1” saniye sonra topumuzu ateşliyoruz.Dördüncü satırda AddForce fonksiyonu ile modelimize kuvvet uyguluyoruz.Bu kuvveti, Vector3.forward yani ileri yönde uyguluyoruz ve bin “1000” gücünde uyguluyoruz.

Beşinci satırda, RagDollKontrol fonksiyonumuzu çağırıyoruz.Paremetre değerini ise, true olarak belirliyoruz.Böylece Collider bileşenlerimiz aktif olurken, isKinematic özelliğini pasif hale getirmiş oluyoruz.Altıncı satırda ise, “Zaman” değişkenimizin değerini sınıflıyoruz.Son satırda, bool türündeki “Atesle” değişkenimizin değerini false olarak belirliyoruz.

RagDollKontrol (false);

Son olarak, start() fonksiyonumuzun içerisine bu kodu yazıyoruz.Böylece projeyi başlattığımız zaman, yazdığımız fonksiyon aktif oluyor ve modelimiz üzerindeki ragdoll fiziğini pasif hale getirmiş oluyoruz.Ve istediğimiz zaman space (boşluk) tuşuna basarak, bu ragdoll fiziğini aktif hale getiriyoruz.Böylece topumuzdan insan modelimizi fırlatıyoruz.Bu arada gerçeğini görmek isteyenler google’da “Gemma Kirby Cannonball Human” kelimelerini aratabilirler.

Evet bu yazımızın da sonuna geldik.Yazmış olduğumuz script dosyasını, Hierarchy penceresinde modelimizin ebeveyn (parent) nesnesinin üzerine sürükleyip bırakıyoruz.Böylece tüm çocuk (child) nesnelerine erişip, istediğimiz bileşenleri kontrol edebiliyoruz.Ben ekstra olarak projeye kamera takip scripti yazdım.Böylece ragdoll fiziğini daha iyi görebileceksiniz.Evet bir sonraki yazıda görüşmek üzere…

Unity-Ragdoll-Nasıl-Kullanılır-How-to-do-Easy-Unity3D-Ragdoll-Physics