Birlikte öğreniyoruz...

Unity Oyun motorunu etkili bir şekilde kullanmak istiyorsak “Transform” sınıfının işlemlerine hakim olmamız gerekiyor. O yüzden burada anlattıklarımı sadece okuyarak geçmeyip mutlaka tekrar edip, faklı şekillerde kullanmaya özen göstermenizi öneririm.

Aslında önceki derslerimizden “Transform” kelimesine yabancı değilsiniz. Hem Unity objelerinin genel konusunda transform bileşenini incelemiştik hem de bir önceki Vector3 sınıfı inceleme konusunda biraz bahsetmiştik.

Yine de genel mantığın üzerinden tekrar geçeceğim ve sonra özelliklerini incelemeye başlayacağız.

Transform Sınıfı

Transform için bir objenin sahne üzerinde olan pozisyonu, boyutu ve rotasyonunu vermemizi sağlayan bir bileşen yani sınıftır diyebiliriz. Sahnenize herhangi bir obje eklediğinizde “Inspector” alanında otomatik olarak “Transform” bileşenin eklendiğini görebilirsiniz.

Aslında bizim “Transform” sınıfıyla yaptığımız işlemde objelerin position, rotation ve scale özelliklerine müdahale ederek objelere istediğimiz şekilde hükmetmeye çalışmak oluyor.

“Inspector” alanında yer alan tüm bileşenleri kaldırabilirsiniz ama “Transform” bileşenini kaldıramayız.

Hadi o zaman başlayalım.

Position Özelliği

“Transform” sınıfının “Position” özelliği, bir objeyi sahnede istediğimiz konuma taşımamızı sağlar.

Aşağıdaki örnekteki gibi transform.position yazarak objenin pozisyon bilgilerine erişiyoruz ve new Vector3(1f, 2f, -5f); diyerek oyun başladığında sahnede taşıyacağımız pozisyonu belirliyoruz.

Not: Daha önceki derslerde gördüğümüz gibi “transform” sınıfı Vector3 tipinde değer alır.

public class TransformDersleri : MonoBehaviour
{
    void Start()
    {
        transform.position = new Vector3(1f, 2f, -5f);        
    }

} 

Farklı bir örnek olarak ise eğer objenin sadece belirli bir koordinatını yani sadece Z ekseninde pozisyonunu değiştirmek isteyebilirsiniz. X ve Y eksenleri mevcut pozisyonuyla aynı kalsın ama Z ekseninde istediğim yere taşınsın isterseniz aşağıdaki gibi transform.position.x anahtar kelimesini kullanarak işlem gerçekleştirebilirsiniz.

public class TransformDersleri : MonoBehaviour
{
    void Start()
    {        
        transform.position = new Vector3(transform.position.x, transform.position.y, -5f);
    }

}

Translate Metodu

“Translate” metoduyla objemizi sahnede belirtilen değerler kadar hareket etmesini sağlarız. Update fonksiyonu içerisinde kullanarak bu işlemin sürekli olmasını sağlayabiliriz.

Örneğin aşağıdaki gibi X ve Y ekseni sabit kalsın ve oyundaki her karede Z ekseninde 0.1f hareket etsin diyebiliriz.

public class TransformDersleri : MonoBehaviour
{
    private void Update()
    {
        transform.Translate(new Vector3(transform.position.x, transform.position.y, 0.1f));
    }
}

Şuan bu kodu çalıştırdığınızda objenin bir anda gözden kaybolduğunu göreceksiniz. Merak etmeyin yavaş yavaş basitten zora doğru gideceğiz.

forward Özelliği

“Forward” özelliği ile bir objeyi sadece Z ekseninde sürekli olarak hareket etmesini sağlayabiliriz.

Bir önceki konuda bahsettiğimiz “Translate” metodu üzerinde bu özelliği kullanacağız. Bu sefer teker, teker pozisyon bilgisi vermek yerine sadece transform.forward yazıyoruz.

public class TransformDersleri : MonoBehaviour
{
    private void Update()
    {
        transform.Translate(transform.forward);
    }
}

Bu kodu Unity oyun motoru üzerinde çalıştırdığımızda objenin Z ekseni boyunca sürekli olarak hareket ettiğini görebilirsiniz.

up Özelliği

“Transform.forward” özelliği ile benzer bir işlem gerçekleştirmektedir. “Forward” ise Y ekseni boyunca yukarı doğru hareket etmesini sağlayacaktır.

public class TransformDersleri : MonoBehaviour
{
    private void Update()
    {
        transform.Translate(transform.up);
    }
}

right Özelliği

“Transform.forward” ve “Transform.up” benzeri işlem gerçekleştiren son özellik ise “Transform.right” özelliğidir. Bu özellik sayesinde tahmin edeceğiniz üzere X ekseni üzerinde sağ tarafa doğru sonsuz bir hareket gerçekleştirir.

public class TransformDersleri : MonoBehaviour
{
    private void Update()
    {
        transform.Translate(transform.right);
    }
}

Şimdi right, up ve forward özelliklerini çalıştırdığınızda objenizin hızlı bir şekilde hareket ettiğiniz gördünüz. Peki o zaman bunu süreyi biraz yavaşlatalım. Bunun için bir önceki derste gördüğümüz Time.deltaTime özelliğini kullanacağız.

public class TransformDersleri : MonoBehaviour
{
    private void Update()
    {
        transform.Translate(transform.forward * Time.deltaTime);
    }
}

Çarpma matematiksel operatör işlemini kullanarak Time.deltaTime kısmını devreye soktuk ama hızda değişiklik yapmak isterseniz içerisine transform.Translate(transform.forward * Time.deltaTime * 2f); şeklinde yeni bir çarpan ekleyebilirsiniz.

Rotate Metodu

“Transform.Rotate” metodu ise bir objenin kendi ekseni etrafında hareket etmesini sağlayacağız. Bu kısımda da aslında Unity ekranında objemizin “Inspector” alanında yer alan “Rotation” değerlerini değiştirmiş olacağız.

Tıpkı “Transform.Translate” metodunda olduğu gibi update içerine yazarak hareketin sürekliliğini sağlayabiliriz.

Örneğin aşağıdaki kodda new Vector3(1f, 0f, 0f) yazarak sadece X ekseninde 1f kadar hareket etmesini söyledik ve bunu update komutuna yazdığımız için sürekli olarak 1f değerinde dönmektedir. Aynı şekilde Y eksenine değer verip X ve Z eksenlerine sıfır değerini verirseniz Y ekseninde dönüşünü gerçekleştirecektir.

public class TransformDersleri : MonoBehaviour
{
    private void Update()
    {
        transform.Rotate(new Vector3(1f, 0f, 0f));
    }
}

Dönüş hızını ayarlamak için ise önceki örneklerimizdeki gibi Time.deltaTime özelliğini aşağıdaki gibi kullanarak yavaşlatabilir ya da hızlandırabilirsiniz.

public class TransformDersleri : MonoBehaviour
{
    private void Update()
    {
        transform.Rotate(new Vector3(0f, 0f, 1f) * Time.deltaTime * 4f);
    }
}

Ayrıca dönüşü daha doğal yapabilmemiz için “transform.Rotate” metoduna farklı bir parametre daha ekleyebiliyoruz. Ekleyebileceğimiz iki parametre ise Space.Self ve Space.World parametreleridir.

Her iki parametreyi yazarak test ettiğinizde arada bir fark görebilirsiniz. Ama biraz detaylı bakmanız gerekcektir.

Space.Self: Dönüş işlemini kendini referans alarak yapmaktadır. Yani olduğu yerde bir dönüş işlemi gerçekleştirir.

Space.World: Dönüş işlemini dünya da boşlukta dönüyormuş gibi gerçekleştirmektedir.

public class TransformDersleri : MonoBehaviour
{
    private void Update()
    {
        transform.Rotate(new Vector3(0f, 0f, 1f), Space.World);
    }
}

İpucu: transform.Rotate(new Vector3(0f, 0f, 1f), Space.World); yerine kısa yazımı olan transform.Rotate(0f, 0f, 1f, Space.World) yazımını kullanabilirsiniz.

LookAt Metodu

Transform.LookAt çalışma modeli

“Transform.LookAt” metodu ile bir objeyi farklı bir objeye göre hareket ettirebilirsiniz. Fakat bunu objenin peşinden gidiyormuş gibi düşünmeyin. Tıpkı bir kameranın bakış açısı gibi atanan obje hangi yöne hareket ederse diğer objede o yöne doğru döner.

Aşağıdaki örnekte public Transform birinciObje, ikinciObje; yazarak iki adet Transform türünde public erişim belirleyicisine sahip obje oluşturdum. Objelerin Unity üzerinden atamasını gerçekleştirdikten sonra birinciObje.transform.LookAt(ikinciObje); yazarak birinci objeye, ikinci obje ne tarafa giderse ona doğru bak demiş olduk.

public class TransformDersleri : MonoBehaviour
{
    public Transform birinciObje, ikinciObje;
   
    private void Update()
    {
        birinciObje.transform.LookAt(ikinciObje);
    }
}

Ayrıca Vector3 sınıfından bir parametre daha ekleyerek objenin takip etme sistemini değiştirebilirsiniz. Vereceğiniz parametre doğrultusunda sabitleyerek kendi ekseni etrafında dönerek takip edecektir.

birinciObje.transform.LookAt(ikinciObje, Vector3.up);
birinciObje.transform.LookAt(ikinciObje, Vector3.down);
birinciObje.transform.LookAt(ikinciObje, Vector3.forward);
birinciObje.transform.LookAt(ikinciObje, Vector3.back);
birinciObje.transform.LookAt(ikinciObje, Vector3.left);
birinciObje.transform.LookAt(ikinciObje, Vector3.right);

childCount Özelliği

Oyun anında “Hierarchy” alanında yer alan objelerin hiyerarşik yapısını çokça kullanmamız gerekecek. transform.childCount özelliği sayesinde Parent – Child yapısında olan obyenin çocuklarının sayısını döner yani bir objenin altında olan alt objelerin sayısını dönmektedir.

transform.childCount özelliği hiyerarşi yapısı.

Örneğin yukarıdaki hiyerarşi yapısında “Dusman” isimli objeye bağlanmış bir script üzerinden aşağıdaki kodu çalıştırdığımızda bize 4 adet alt objesinin olduğunu geri dönecektir.

public class TransformDersleri : MonoBehaviour
{
    private void Update()
    {
        Debug.Log(transform.childCount); 
    }

}

hierarchyCount Özelliği

childCount” özeliğine benzer şekilde çalışır fakat “hierarchyCount” objeye bağlı alt objeleri ve o objelere bağlı diğer alt objelerin sayısını döndürür.

unity transform childCount ozelligi

Yukarıdaki görselde “Dusman” objesinin altında toplamda 12 adet obje gözüküyor. “hierarchyCount” özelliğini kullandığımızda, 12 alt objeye ek olarak kendisini de dahil ekleyerek toplamda bize 13 sonucunu dönecektir.

public class TransformDersleri : MonoBehaviour
{
    private void Update()
    {
        Debug.Log(transform.hierarchyCount); 
    }

}

GetChild Metodu

GetChild” metodu, ana objenin altında yer alan alt objelere erişmemizi sağlamaktadır.

Örneğin bir ana obje altında yer alan objelerin isimlerini öğrenmek için, daha önce öğrendiğimiz transform.childCount komutu ile bir for döngüsüne sokabiliriz. Her döngüye girdiğinde alt objelerin isimlerini almak için transform.GetChild(i).name komutunu kullanabiliriz.

public class TransformDersleri : MonoBehaviour
{
    private void Start()
    {
        for (int i = 0; i < transform.childCount; i++)
        {
            Debug.Log(transform.GetChild(i).name);
        }
    }
}
transform.getChild Debug çıktısı

transform.GetChild kullanıma biraz daha detaylı bir örnek verelim. Mesela oyun başladığında objeye ait tüm alt objelere erişerek bir bileşenin özelliğini değiştirmek istediğinizde aşağıdaki kodu kullanabiliriz.

public class TransformDersleri : MonoBehaviour
{
    private void Start()
    {
        for (int i = 0; i < transform.childCount; i++)
        {
            transform.GetChild(i).GetComponent<Rigidbody>().isKinematic = true;
        }
    }
}

Tüm alt objelere “Rigidbody” bileşenini ekledikten sonra yine transform.childCount komutuyla alt objelerinin sayısı kadar for döngüsünün çalışmasını söyledik. Sonrasında ise transform.GetChild(i) ile sırasıyla alt objeleri yakalayarak GetComponent<Rigidbody>() ile Rigidbody bileşenlerini yakaladık ve “isKinematic” özelliğini değiştirdik.

SetParent Metodu

“SetParent” metodu ile bir objeyi başka bir objenin alt objesi haline getirerek hiyerarşik bir yapı oluşturabiliriz.

transform.SetParent Metodu Kullanımı

Örneğin aşağıdaki kodda, public Transform ustObje, altObje; yazarak iki adet “Transform” türünde nesne ekledik. C# Script dosyasının bağlı olduğu obje üzerinden dışarıdan obje atama işlemini gerçekleştirdikten sonra ustObje.transform.SetParent(altObje); yazarak “altObje” isimli objeye “ustObje” isimli objeyi parent olarak kabul etmesini yazdık.

public class TransformDersleri : MonoBehaviour
{
    public Transform ustObje, altObje;
    private void Start()
    {
        ustObje.transform.SetParent(altObje);
    }
}

Quaternion Sınıfı

Bu derste incelediğimiz “transform” sınıfına benzer özellikleri ve metodları bulunur. Yine “transform” sınıfı gibi objelerin dönüş işlemlerimde kullanılır fakat transform sınıfında bazen hesaplamalarıyla ilgili sorunlar (Gimbal lock sorunu) yaşandığı için ve Quaternion sınıfının 4. bir açı mantığı olduğu için, hesaplamalarda daha net sonuçlar alabilmek için tercih edilir.

LookRotation Metodu

“Transform” sınıfının “LookAt” metodu yaptığı işlemin aynısı yani bir objenin bir objeyi takip etmesini sağlar.

Quaternion.LookRotation Metodu

Burada fark ettiyseniz, takip eden obje ile takip edilecek obje arasındaki fark alınarak Quaternion.LookRotation(fark, Vector3.up); sınıfına ekleniyor. Bu şekilde takip hesaplamalarında daha doğru sonuçlar vermektedir.

public class TransformDersleri : MonoBehaviour
{
    public Transform takipEdilenObje;
    private void Update()
    {
        Vector3 fark = takipEdilenObje.position - transform.position;
        transform.rotation = Quaternion.LookRotation(fark, Vector3.up);
    }
}

Angel Metodu

Angel metodu iki obje arasındaki açıyı bize derece olarak döndürür.

Quaternion.Angel Metodu

Transform türünde yeni bir obje oluşturduktan sonra dışarıdan obje ataması gerçekleştiriyoruz. Sürekli güncellemesi için update fonksiyonuna Quaternion.Angle(transform.rotation, hedefObje.rotation); yazıyoruz. Böyle “hedefObje” isimli objenin ana objeye olan açısını alabiliriz.

public class QuaternionDersleri : MonoBehaviour
{
    public Transform hedefObje;
    private void Update()
    {
        float objelerAci = Quaternion.Angle(transform.rotation, hedefObje.rotation);
        Debug.Log("Aradaki Açı: " + objelerAci);
    }
}

Inverse Metodu

Quaternion sınıfındaki Inverse metodu ile hedef olarak belirlediğiniz objede gerçekleşen “Rotation” işlemleri, ana objede de tam tersi şekilde gerçekleşir.

Quaternion.Inverse Metodu

Transform türünde yeni bir obje oluşturduktan sonra dışarıdan obje ataması gerçekleştiriyoruz. İşlemin her hareketimizde güncellemesi için update fonksiyonunun içerisine transform.rotation = Quaternion.Inverse(hedefObje.rotation); yazarak ana objemizin hedef objenin rotasyonunu ters şekilde işlemesini sağlıyoruz.

public class QuaternionDersleri : MonoBehaviour
{
    public Transform hedefObje;
    private void Update()
    {
        transform.rotation = Quaternion.Inverse(hedefObje.rotation);
    }
}

Euler Metodu

Quaternion sınıfındaki Euler metodu ile oyunumuzun başlangıcında ya da belirli bir aşamasında istediğiniz açıda yön değiştirmesini sağlayabilirsiniz. Euler metodu X,Y ve Z koordinat bilgileri parametre olarak alır ve bu parametrelerde belirtilen açıları sırasıyla uygulamaya geçirir.

Örneğin aşağıdaki kod yapısında önce scriptin bağlı olduğu objeye “Quaternion.Euler(90,0,0)” yazarak, oyunun açılışıyla beraber objemizin X koordinatının 90 derece değişmesini belirtmiş oluyoruz.

public class QuaternionDersleri : MonoBehaviour
{
    private void Start()
    {
        transform.rotation = Quaternion.Euler(90,0,0);
    }
}

Not: Euler metodunu, update metodu içinde kullansak bile yapısı gereği sadece bir kez çalışmaktadır.

identity Özelliği

Quaternion sınıfındaki identity özelliği sayesinde objede olan mevcut rotasyonları sıfırlayabilirsiniz.

Örneğin objenizin rotation bilgileri (0,90,30) derece açıda duruyorsa ve transform.rotation = Quaternion.identity; yazarsanız objeniz açılışla birlikte ilk halini yani (0,0,0) rotasyon değerlerine geçecektir.

public class QuaternionDersleri : MonoBehaviour
{
    void Start()
    {
        transform.rotation = Quaternion.identity;
    }
}

Bir sonraki dersimiz olan Instantiate Metodu ve Prefabs Kullanımı dersine aşağıdaki bağlantıdan erişebilirsiniz.