Unity’de Nesne Parçalamak
Merhaba, bir önceki yazımızda Unity ile hedef bir nesnenin etrafında başka bir nesneyi nasıl döndürebileceğimizi öğrenmiştik.Bu dersimizde ise sahnemizdeki nesneleri parçalamayı öğreneceğiz.Evet önce yeni bir proje oluşturalım ve dersimize hızlıca geçiş yapalım.
Sahnemizin hazırlık aşaması.
Bu dersimiz için belirlediğim senaryo, bir masa üzerinde tokmak ile ceviz kırmak.Aslında senaryoya baktığımız zaman, hangi nesnenin ne görev olacağını kestirmiş oluyoruz.Ama yinede açıklayalım.Tokmağımız tetikleyici görevi görecektir.Cevizlerimiz ise parçalanma görevi görecek.Şimdi sahnemize nesnelerimizi eklemeye başlayalım.aİlk olarak bir Plane nesnesi ekliyoruz.Bu nesne bizim masamızı oluşturacak.
Daha sonra bir Cylinder nesnesi ekliyoruz.Bu silindir cevizleri üzerinde kırdığımız mermeri oluşturacak.Bu nesnemizin Inspector penceresinden collider bileşenini silip yerine Box Collider bileşenini veriyoruz.Bunlara ister kaplama isterseniz de renk verebilirsiniz.Tercih sizin, ben senaryoya uygun olarak kaplama ekledim.Böylelikle daha güzel bir görüntü oluştu.Şimdi sahnemize bir Cube nesnesi ekleyelim.
Bu nesne birazdan parçalayacağımız cevizleri oluşturacak.Nesnenin konumunu, mermer olacak nesnemizin tam ortasına konumlandırıyoruz.Sonra yeni bir etiket oluşturuyoruz ve nesnemize veriyoruz.Bu nesnemize Inspector penceresinden bir Rigidbody bileşeni ekliyoruz.Daha sonra bu nesneyi tutup, Project penceresine sürüklüyoruz.Daha sonra bu nesnemizin boyutunu küçülterek, yine Project penceresine sürükleyip bırakıyoruz.
Tokmak ile parçaladıkça yeniden çıkacağı için, bu nesnelerimizin Prefab olması gerekiyor.Daha sonra bu nesnemizi Hierarchy penceresinden siliyoruz.Şimdi tokmağımızın yapımına geçebiliriz.Bunun için Hierarchy penceresinde sağ tıklayarak, Create Empty seçimini yapıyoruz.Daha sonra bu boş nesnemize bir isim veriyoruz ve üzerine sağ tıklayarak bir adet Cube, bir adette Cylinder nesnesi oluşturuyoruz.
Bu iki nesnede, boş nesnemizin çocuğu konumunda olmalıdırlar.Silindir nesnemizin, Inspector penceresinden collider bileşenini silip yerine Box Collider bileşenini ekliyoruz.Burası önemli.Bu nesnelerimizi de tokmağa benzer bir forma sokuyoruz.Cube nesnesi tokmağımızın sapını oluştururken,Cylinder nesnesi tokmağımızın baş kısmını oluşturacak.Daha sonra istersek materyallerini ekliyoruz.Sahnemizin son hali aşağıdaki gibidir.
Cevizleri kırmaya başlayalım.
Şimdi Project penceremizde bir C# Script dosyası oluşturalım.Dosyamıza bir isim verdikten sonra sürükleyip, tokmak başını oluşturacak nesnemizin üzerine bırakalım.Bu bizim parçalanma işini yapacağımız script dosyamız olacak.Bir tane daha C# Script dosyası oluşturuyoruz.Bu script dosyasınıda tutup, ceviz parçalarını oluşturacak Prefab’ın üzerine bırakıyoruz.Artık kod yazmaya hazırız.
public GameObject ParcalanacakNesne; public GameObject NesneParcalari; public GameObject ParcalayacakNesne; public GameObject TemasEdenNesne; public float zamanlayici; public bool yeniCevizKoy;
Evet ilk olarak parçalama işlevini üstlenecek scriptimiz için değişkenlerimizi oluşturmakla başlıyoruz.Üstte dört adet GameObject oluşturduğumu görüyorsunuz.İlk iki satıra az önce oluşturmuş oluşturduğumuz prefab nesnelerimiz gelecek.Üçüncü satıra tokmağımız gelecek.Dördüncü satıra ise, tokmağımızın temas eden noktası yani tokmak başı gelecek.Beşinci satırda float türünde bir değişken yazdık.Bu bizim cevizlerimizin belli arayla ortay çıkmasını sağlayacak.Son satırımızda ise bir bool değişkeni yazdık.Bu değişken ile de, zamanlayıcımızı başlatıp durduracağız.
Instantiate(ParcalanacakNesne, ParcalanacakNesne.transform.position, ParcalanacakNesne.transform.rotation); ParcalayacakNesne = transform.parent.gameObject; TemasEdenNesne = this.gameObject; zamanlayici = 1f;
Şimdi start() fonksiyonumuzun içerisine bu kodları yazalım.İlk satırda, Instantiate fonksiyonunu kullanarak ilk cevizimizin sahnemizde oluşmasını sağlıyoruz.Bu fonksiyonun aldığı parametrelere bakacak olursak, ilk olarak klon olacak nesnenin değişkenini yazıyoruz.Daha sonra bu nesnenin pozisyonunu alıyoruz ve en sonda bu nesnenin rotasyonunu alıyoruz.İkinci satırda “ParcalayacakNesne” değişkenimizi, bu scriptin ekli olduğu nesnenin ebeveynine eşitliyoruz.Üçüncü satırda, “TemasEdenNesne” değişkenine direk bu nesneye eşitliyoruz.Çünkü tetikleyici görevini bu nesne görecek.Son satırda ise, zamanlayıcımızı bir “1” olarak ayarlıyoruz.
void TokmakHareketi(){ if(Input.GetKeyDown(KeyCode.Space)) { ParcalayacakNesne.transform.position = new Vector3 (ParcalayacakNesne.transform.position.x, 2.75f, 1.20f); ParcalayacakNesne.transform.rotation = Quaternion.Euler(-45f, 0, 0); yeniCevizKoy = true; } if(Input.GetKeyUp(KeyCode.Space)) { ParcalayacakNesne.transform.position = new Vector3 (ParcalayacakNesne.transform.position.x, -0.31f, -0.37f); ParcalayacakNesne.transform.rotation = Quaternion.Euler(7f, 0, 0); yeniCevizKoy = false; zamanlayici = 1f; } }
Evet daha sonra yeni bir fonksiyon oluşturuyoruz.Bu fonksiyonumuzun içerisine tokmağımızın animasyonlarını yazacağız.Öncelikle bir koşul belirliyoruz.Bu koşulumuza, “eğer klavyeden space tuşuna basılırsa, aşağıdaki işlemleri gerçekleştir.” diyoruz.Bu işlemlere bakacak olursak, “ParcalayacakNesne” değişkenimize yeni bir pozisyon ve rotasyon veriyoruz.
Parentez içerisinde bulunan değerleri, ben sahnemde tokmağımın durmasını istediğim pozisyona alarak buldum.Sizde tokmağınızın space tuşuna basınca hangi konumda ve açıda olmasını istiyorsanız bu şekilde belirleyebilirsiniz.Daha sonra bool değişkenimi true olarak belirliyoruz.Böylelikle zamanlayıcımızı başlatabiliriz.İkinci koşulumuzda da, “space tuşu bırakılırsa, aşağıdaki işlemleri gerçekleştir.” diyoruz.
Bu seferde tokmağımızın konumunu ve açısını sahnedeki ilk konumundan biraz aşağıya alıyoruz.Sonra bool değişkenimizi false yapıyoruz.Çünkü elimizi space tuşundan çektiğimiz için zamanlayıcıyı durdurmamız gerekiyor.Son olarak da, zamanın baştan başlaması için zamanlayıcımızı bire “1” eşitliyoruz.
void OnCollisionEnter(Collision Kontrol){ if (Kontrol.gameObject.tag == "ceviz") { Destroy (Kontrol.gameObject); for (int i = 0; i < 20; i++) { Instantiate(NesneParcalari, ParcalanacakNesne.transform.position, ParcalanacakNesne.transform.rotation); } } }
Şimdi bir tetikleyici fonksiyonu yazıyoruz.Bu projede Collision fonksiyonunu tercih ediyoruz.Çünkü tokmağımızın cevizlerin içinden geçmemesi gerekiyor.Fonksiyonumuzun içerisine bir koşul yazıyoruz.Eğer çarptığımız nesnenin etiketi “ceviz” ise koşulumuz doğru oluyor.İlk olarak, çarptığımız nesneyi yok ediyoruz.Bunu Destroy fonksiyonu ile yapıyoruz.Daha sonra bir For döngüsü yazıyoruz.
Bu döngü ile cevizimiz kırıldıktan sonra, bir sürü ceviz parçası oluşturacağız.Ben 20 tane parça oluşturdum.Siz bu sayıyı arttırabilir yada azaltabilirsiniz.Döngümüzün içerisine Instantiate fonksiyonunu yazıyoruz.Sadece ilk parametresini, cevizimizin paçalarını oluşturacak Prefab‘ın bulunduğu değişken ile değiştiriyoruz.
TokmakHareketi (); if(yeniCevizKoy) { zamanlayici -= Time.deltaTime; if(zamanlayici < 0) { Instantiate(ParcalanacakNesne, ParcalanacakNesne.transform.position, ParcalanacakNesne.transform.rotation); yeniCevizKoy = false; zamanlayici = 0; } }
Gelelim update() fonksiyonun içerisine.İlk olarak az önce oluşturduğumuz fonksiyonu yazıyoruz.Daha sonra yeni bir koşul belirliyoruz.Eğer bool değişkenimizin değeri true olarak belirliyse, koşulumuz doğru oluyor.İstersek bu koşulu “yeniCevizKoy == true” olarak da yazabilirdik.İkisi aynı anlama geliyor.False olması içinse, “!yeniCevizKoy” olarak yazıyoruz.Koşulumuzun içine bakacak olursak, ilk olarak zamanlayıcımızı geriye doğru başlatıyoruz.
Daha sonra bir koşul daha yazıyoruz ve zamanlayıcımız sıfırdan “0” küçük olursa sahnemize Instantiate fonksiyonu ile yeni bir ceviz ekliyoruz.Daha sonra, bool değişkenimizi false yapıyoruz.Ve son olarak da, zamanlayıcımızı sıfırlıyoruz.Evet ilk script dosyamız hazır.Şimdi Project penceresinde bulunan Prefab‘ları Inspector penceresinde yerlerine yerleştirelim.
Şimdi ikinci script dosyamıza gelelim.Bu dosyamızı sadece ceviz parçalarını sahnemizden yok etmek için kullanacağız.Bunu Destroy fonksiyonu ile gerçekleştireceğiz.
Destroy(this.gameObject, Random.Range(0, 10f));
Evet, start() fonksiyonumuzun içerisine bu kodu yazıyoruz.Böylelikle bu script dosyasının ekli olduğu nesnelerin yok ediyoruz.Bunu yaparken de hepsini aynı anda sahnemizden silmemesi için, rastgele bir zaman belirliyoruz.Bunu Random fonksiyonu ile yapıyoruz.Sıfır “0” ile on “10” arasında rastgele bir süre alıyor ve o sürede sahneden siliniyor.Bu süreyi kendinize göre belirleyebilirsiniz.Ayriyeten her nesnenin süresi birbirinden farklı olacağı için, sahneden aynı anda silinmiyorlar ve daha doğal bir görüntü oluşuyorlar.
Evet uzun bir yazı oldu.Projede kullandığımız her bir elemanı detaylı olarak açıklayınca, haliyle yazıda uzuyor.Zaten amacımda bu olduğu için bir sorun olduğunu zannetmiyorum.Bir projemizin de sonuna geldik.Bir sonraki yazıda görüşmek üzere…