Merhaba dostlar, bu yazımızda Unity Vector3 Nedir ? sorusunu cevaplayıp, Vector3 adlı değişken tipinden, kullanım alanlarından ve yararlanabileceğimiz fonksiyonlardan bahsedeceğim. Vector3 Unity programı üzerinde kullanabileceğimiz, içerisinde 3 boyuttaki eksenlere denk gelen x,y,z adlı 3 float tipli değişken bulunduran, yani vektörel bir büyüklüğü belirtmek için kullandığımız değişken tipidir. Bu veri tipini Transform ile konumlandırmada, yön değiştirmede, boyut değişimlerinde ve özellikle Rigidbody bileşeni ile fizik işlemleri gerçekleştirirken sık sık kullanıyoruz. Benzer isimli olan Vector2 tipiyle fazlasıyla ortak özelliğe ve fonksiyona sahip ancak Vector2 sadece x ve y eksenleri için bileşenleri barındırıyor. Onun detaylarına farklı bir yazıda gireceğiz.

3 boyutlu uzayı ve eksenlerini düşündüğümüz, sağ yön ekseni (x), yukarı yön ekseni (y) ve ileri yön ekseni (z) bizim 3 boyut dediğimiz yapıyı oluşturuyor. İlkokuldan hatırlarsınız, sayı doğrusunu kullanarak bir noktanın konumunu belirtiyorduk. Sayı doğrusu tek başına aslında 1 ekseni belirtmekte, bir boyutlu bir dünyadaki hareketi göstermekte. Daha sonra ilerleyen aşamalarda çeşitli derslerden hatırlayacağınız üzere bir de yukarı yönlü bir sayı doğrusu eklendi buna. Yatay olana x, dikey olana y isimlerini vererek ilerledik. 3 boyutluyu okulda görmemiş olabilirsiniz ancak Unity ile biraz haşır neşir olduysanız o 3. eksenin, z ekseninin nasıl çalışacağını da tahmin edebilirsiniz. İşte Vector3 değeri, basitçe her bir eksenin değerini kendi içerisinde bir değişkende tutmamızı sağlayan ve kolaylıkla vektörel işlemleri uygulayabilmemizi sağlayan bir yapı.

Unity Vector3 Nedir Eksen
Unity Vector3 Nedir Eksen

Şimdi bu bahsettiğim 3 değişkenin ayrı ayrı eksenleri temsil ettiğini anlamışsınız, umuyorum ki. Bunu kavradıktan sonra artık Vector3 tipi için matematiksel işlemlerden bahsedeyim. Öncelikle şunu belirtmem gerekiyor, Vector3 tipindeki değişkenler birbiriyle yalnızca toplama ve çıkarma işlemi yapabilir. Çarpma ve bölme işlemlerinde ise int, float gibi diğer tipler kullanabiliriz. Unity’nin sağladığı farklı fonksiyonlar bulunuyor ancak temel matematik kullanmından bahsedeceğim için, yazının devamına bırakıyorum o konuyu. 

Vector3 cinsinde toplama ve çıkarma işlemi gayet basit. Her bir sayı doğrusu, eksen değerini, diğer vektörün eksen değeriyle işleme sokuyoru. Yani a=(1,5,3) ve b=(3,5,2) şeklinde iki değişken tanımlayalım, kodlamada böyle tanımlanmıyor bu arada sadece anlatım amacıyla böyle yazıyorum. Şayet a-b işlemi gerçekleştirirsek çıkacak sonuç (-2,0,1) olacaktır. X ekseninde 1-3, y ekseninde 5-5 ve son olarak z ekseninde 3-2 işlemini gerçekleştirerek bu sonuca erişmiş olduk. Ancak dikkatinizini çekmiş olabilir, şayet b-a işlemi yaparsak sonuç aynı olmayacak. b-a işlemini kafanızda yapmanızı istiyorum şimdi. Sakin sakin sabredin, cevap geliyor. Evet, b-a=(2,0,-1) çıktı. İncelediğimizde bu durum elde ettiğimiz vektörün büyüklük, uzunluk (magnitude) değerini farklılaştırmayacaktır. Ancak vektörler büyüklük dışında aynı zamanda yön de belirttiği için çok farklı bir yöne kuvvet uygulamamıza, hareket etmemize sebep olabilir. Tabii ki bu işlem çıkarma işlemlerinde geçerli, a+b ve b+a her zaman birbirine eşit olacaktır. 

Sıra çarpma ve bölmede, bu konuda gayet basit aslında. Yine yazının öncesinde belirtmiş olduğumuz a değişkenini kullanalım. Bir vektörle çarpma işlemi gerçekleştirdiğinizde çarpan olarak ancak int, float tipi değişkenler kullanabilirsiniz demiştim. Hemen uygulayalım, örneğin a*1.5f diyelim. Bu aşamada az çok tahmin edeceğinizi umuyorum. Sonuç (1.5, 7.5, 3) şeklinde olacak. Evet, çarpan olarak verdiğimiz değişkeni her bir eksen değeriyle ayrı ayrı çarpıp yeni eksen değerlerini elde ediyoruz. Şimdi bölme işlemi için de aynısını yapalım, hatta biraz pratik olması için size bırakıyorum. a değişkenini ilk başta tanımladığımız değerlere geri döndürmenizi istiyorum. Sakin sakin düşünün yine, biraz matematik pratiği olsun. Özellikle oyun programlamada bol bol ihtiyacımız olan bir şey matematik. Cevap : 1,5f .

Unity Vector3 İle Kullanılabilecek Kodlar

Unity Vector3 ile kullanılabilecek kodlar konusunu 3 başlık altında anlatacağım. Bu başlıklar özellikler-değişkenler, public metodlar ve static metodlar şeklinde ayrılır. Bu başlıklara geçmeden önce Vector3 sınıfını, tipinin kurucu fonksiyonundan bahsedeyim. Bu sayede öncelikle bir vektör değişkeni nasıl oluşturulur öğrenmiş olalım.

//yeni bir vektör oluşturur
//ve x =1, y=3,z=5 değer atamalarını yapar.
Vector3 ilkVector=new Vector(1,3,5);

Böylece bir vektör değişkeni elde etmiş olduk. Şimdi alt başlıklara geçmeden bazı statik özelliklerden, değişkenlerden bahsedeceğim. Bunlar daha çok uzun uzun vektör değerleri yazmaktan bizi kurtarmak için olan değişkenler aslında. Önce toplu halde açıklayıp sonrasında tek bir kod blogunda kullanımını göstereceğim.

  • back : Vector3(0,0,-1) yazmanın kısayolu.
  • down : Vector3(0, -1, 0) yazmanın kısayolu
  • forward : Vector3(0, 0, 1) yazmanın kısayolu
  • left : Vector3(-1, 0, 0) yazmanın kısayolu.
  • negativeInfinity : Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity) yazmanın kısayolu
  • one: Vector3(1, 1, 1) yazmanın kısayolu
  • positiveInfinity : Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity) yazmanın kısayolu
  • right : Vector3(1, 0, 0) yazmanın kısayolu
  • up : Vector3(0, 1, 0) yazmanın kısayolu
  • zero : Vector3(0,0,0) yazmanın kısayolu

Özellikler – Erişilebilir Değişkenler

Bu özellikler, değişkenler daha önce belirttiğimizin aksine her bir Vector3 değişkeni için farklı olan özelliklerdir.

magnitude: Vector3 değişkeninin büyüklük, uzunluk değerini float cinsinden döndürür.

normalized: Vector3 değişkenini alıp, x,y,z bileşen değerlerini vektörün boyutu 1 birim olacak şekilde hesaplar. Vectorün sadece büyüklüğünü değiştirir, yönünde bir değişiklik olmaz.

sqrMagnitude : Değişkenin uzunluğunun karesini elde etmemizi sağlar. magnitude özelliğinden daha hızlı çalışır. Çünkü bu uzunluğun hesaplanması adımlarında önce karesi elde edilir, ardından bunun karekökünü almak ve uzunluk değerine ulaşmak daha fazla işlem gerektirir. 

this[int] : değişkenin x,y,z değerine aynı dizilerde olduğu gibi index değerleriyle erişmemizi sağlar. x : 0, y : 1 ve z : 2 index değerine sahiptir.

x : Vektörün x eksenindeki değerini elde etmemizi sağlar.
y : Vektörün y eksenindeki değerini elde etmemizi sağlar
z : Vektörün z eksenindeki değerini elde etmemizi sağlar

    void Start () {
        Vector3 yeniVektor = new Vector3 (3, 4, 5);
        Debug.Log ("Vektör uzunluğu: " + yeniVektor.magnitude);
        Debug.Log ("Vektör normelleştirilmiş hali: " + yeniVektor.normalized);
        Debug.Log ("Vektör uzunluğunun karesi: " + yeniVektor.sqrMagnitude);
        Debug.Log ("İndex ile vektör değerleri : x=" + yeniVektor[0] + " y=" + yeniVektor[1] + " z=" + yeniVektor[2]);
        Debug.Log ("Vektör x değeri: " + yeniVektor.x);
        Debug.Log ("Vektör y değeri: " + yeniVektor.y);
        Debug.Log ("Vektör z değeri: " + yeniVektor.z);
    }
;

Public Metodlar

Angle () : Verilen iki vector değişkeni arasındaki açıyı float tipinde elde etmemizi sağlar. Bu açının alabileceği maksimum değer 180 derecedir olacaktır.

    void Start () {
        Vector3 ileri = new Vector3 (0, 0, 1);
        Vector3 sag = new Vector3 (1, 0, 0);
        Debug.Log ("ileri ve sağ yön vektörleri arasındaki açı :" + Vector3.Angle (ileri, sag));
    }

ClampMagnitude (): Vector değişkeninin yönünü aynı tutarak verilen uzunluğa göre kopyasını oluşturur ve bu kopya vector3 değerini bize döndürür. Bu sayede yönü koruyup daha kısa bir vektörel büyüklüğü sahip halde elde edebiliriz. Eğer verdiğimiz uzunluk değeri varolan vektör büyüklüğünden büyük ise, varolan değeri değiştirmeyecektir. Ayrıca, tam tersi yönde bir vektör elde etmek için büyüklük için negatif değer verebilirsiniz.

    void Start () {
        Vector3 vektor = new Vector3 (3, 4, 5);
        Vector3 birimVektor = Vector3.ClampMagnitude (vektor, 1);
        Vector3 zitYondekiVektor = Vector3.ClampMagnitude (vektor, -vektor.magnitude);
        //Log ekranında değerleri görelim
        Debug.Log ("Orjinal Vektor :" + vektor + " uzunluğu: " + vektor.magnitude);
        Debug.Log ("1 birim haline getirilmiş Vektor :" + birimVektor + " uzunluğu: " + birimVektor.magnitude);
        Debug.Log ("Zıt yöndeki Vektor :" + zitYondekiVektor + " uzunluğu: " + zitYondekiVektor.magnitude);
        //DrawRay ile Scene panelinde görselleştirelim
        Debug.DrawLine (Vector3.zero, vektor, Color.red, Mathf.Infinity);
        //birimvektor için çizeceğimiz çizgi daha kısa olacağı için göremeyebilrsiniz. Bunun için üst satırdaki DrawLine komutunu yorum satırı haline getirip tekrar gözlemleyin
        Debug.DrawLine (Vector3.zero, birimVektor, Color.blue, Mathf.Infinity);
        Debug.DrawLine (Vector3.zero, zitYondekiVektor, Color.green, Mathf.Infinity);
    }

Cross (): Verilen iki vektörün cross product isimli, bu iki vektöre de dik olan bir vektör elde etmemizi sağlar. Değişkenlerin sırası önemlidir, sıraları değiştiğinde elde edilecek sonuç birbirinin zıttı yönde olacaktır. Unity Vektörel işlemlerde, hesaplamalarda sol el kuralını kullanmaktadır.

    void Start () {
        //rastgele vektörler oluşturuyoruz
        Vector3 ilkVektor = new Vector3 (3, 4, 5);
        Vector3 ikinciVektor = new Vector3 (-3, 3, 1);
        Vector3 crossProduct = Vector3.Cross (ilkVektor, ikinciVektor);
        Vector3 tersCrossProduct = Vector3.Cross (ikinciVektor, ilkVektor);
        //DrawRay ile Scene panelinde görselleştirelim
        Debug.DrawLine (Vector3.zero, ilkVektor, Color.red, Mathf.Infinity);
        Debug.DrawLine (Vector3.zero, ikinciVektor, Color.blue, Mathf.Infinity);
        Debug.DrawLine (Vector3.zero, crossProduct, Color.green, Mathf.Infinity);
        Debug.DrawLine (Vector3.zero, tersCrossProduct, Color.yellow, Mathf.Infinity);
    }

Distance (): Verilen iki Vector3 değişkeni arasındaki mesafeyi elde etmemizi sağlar. 

    //düşman objesi yaratıp inspector üzerinde atamayı unutmayın
    [SerializeField]
    Transform dusman;

    void Update () {
        //yarattığımız bir düşman objesi ile aramızdaki mesafeyi belirliyoruz.
        Debug.Log ("Düşman ile aradaki mesafe : " + Vector3.Distance (dusman.position, transform.position));
    }

Dot (): İki vektörün aynı yöne doğru bakıp bakmadığını anlamakta da kullanabileceğimiz, vektörlerin büyüklüklerini aralarındaki açının kosinüsü ile çarparak elde edilen bir sayı döndüren fonksiyondur. Baya karmaşık gelmiş olabilir, farkındayım. Ancak örneği incelemek biraz daha anlamanızı sağlayacaktır. -1 ve 1 arasında değerler döndürür. 1 değeri veriyorsa vektörler aynı yöne bakıyordur, -1 değeri veriyorsa zıt yöne. Eğer 0 değeri veriyorsa iki vektör birbirine dik, aralarında 90 derece var demektir.

    //Düşman objesi oluşturup atamayı unutmayın
    [SerializeField]
    Transform dusman;

    void Update () {
        //eğer düşman objesi tanımlandıysa
        if (dusman) {
            //düşman ile aramızdaki yön değerini vector3 olarak elde ediyoruz
            Vector3 dusmanYonu = dusman.position - transform.position;

            Color isinRengi;
            //Eğer düşman yönü ile bizim ileri yönümüzü kullanarak
            //elde ettiğimiz Dot değeri pozitif ise düşman önümüzde
            //negatif ise düşman arkamızda olacaktır. 
            //önce veya arkada olma durumuna göre ışın için renk ayarı yapıyoruz
            if (Vector3.Dot (transform.forward, dusmanYonu) < 0) {
                Debug.Log ("Düşman Arkamda");
                isinRengi = Color.red;
            } else {
                isinRengi = Color.green;
            }
            //Işın çizdirerek görselleştirelim
            Debug.DrawRay (transform.position, dusmanYonu, isinRengi);

            //bizim ileri yönümüz
            Debug.DrawRay (transform.position, transform.forward, Color.blue);
        }
    }

Lerp (): Lerp fonksiyonu farklı matematiksel değişkenlerde de karşımıza çıkan, iki değer arasında belirli bir orana göre değer almamızı sağlayan fonksiyondur. Örneğin bu fonksiyon sayesinde bir objeyi başlangıç ve bitiş noktaları arasında hareket ettirebiliriz. Verdiğimiz oranın değeri 0-1 arasındadır ve 0 verirsek ilk değeri, 1 verirsek 2.değeri elde ederiz.

    Vector3 baslangicPozisyonu, bitisPozisyonu;

    float oran = 0.5f;

    void Start () {
        //başlangç pozisyonunu x ekseninde -5 konumuna koyuyoruz
        baslangicPozisyonu = Vector3.left * 5;
        //bitis pozisyonunu x ekseninde +5 konumuna koyuyoruz
        bitisPozisyonu = Vector3.right * 5;
        //objeyi başlangıçta 0,0,0 noktasına yerleştiriyoruz
        transform.position = Vector3.zero;
    }

    void Update () {
        //a ve d tuşları ile oranı ne kadar arttıracağımızı belirliyoruz
        float oranArtisi = Input.GetAxis ("Horizontal") * .1f;
        oran += oranArtisi;
        //oran değerinin 0-1 arasında olduğundan emin oluyoruz
        if (oran > 1f) {
            oran = 1;
        } else if (oran < 0) {
            oran = 0;
        }

        //a ve tuşlarına basarak hareket ettirirken, belirlenen iki pozisyon arasında hareketi kısıtlamış oluyoruz böylece
        transform.position = Vector3.Lerp (baslangicPozisyonu, bitisPozisyonu, oran);

    }

LerpUnclamped (): Lerp gibi çalışır, ancak alabileceği oran değeri 1’den büyük veya 0’dan küçük olabilir. Bu sayede ikinci değişkenin ötesine geçebiliriz. iki değer arasındaki oran korunarak ilerler. Yukarıdaki örneğe benzer şekilde bir örnek oluşturduğumu farkedeceksiniz. Bu kısımda 5 değeri yerine 1 kullanmayı tercih ettim, bu değeri değiştirerek sizde harekete nasıl etki ettiğini görebilirsiniz.

    Vector3 baslangicPozisyonu, bitisPozisyonu;

    float oran = 0.5f;

    void Start () {
        //başlangç pozisyonunu x ekseninde -1 konumuna koyuyoruz
        baslangicPozisyonu = Vector3.left * 1;
        //bitis pozisyonunu x ekseninde +1 konumuna koyuyoruz
        bitisPozisyonu = Vector3.right * 1;
        //objeyi başlangıçta 0,0,0 noktasına yerleştiriyoruz
        transform.position = Vector3.zero;
    }

    void Update () {
        //a ve d tuşları ile oranı ne kadar arttıracağımızı belirliyoruz
        float oranArtisi = Input.GetAxis ("Horizontal") * .1f;
        oran += oranArtisi;
        //a ve tuşlarına basarak hareket ettirirken, belirlenen iki pozisyon arasında hareketi kısıtlamış oluyoruz böylece
        transform.position = Vector3.LerpUnclamped (baslangicPozisyonu, bitisPozisyonu, oran);
    }

Max (): Verdiğimiz iki vektörün x,y,z bileşenlerinden en büyük değerleri alarak bize yeni bir Vector3 değişkeni oluşturur.

    //Verilen iki vektör değişkenin en büyük bileşenlerini alarak
    //yeni bir vektor oluşturur;
    void Start () {
        Vector3 vektor1 = new Vector3 (15, -3, 5);
        Vector3 vektor2 = new Vector3 (3, -1, 7);
        Vector3 enBuyukDegerler = Vector3.Max (vektor1, vektor2);
        Debug.Log (enBuyukDegerler);
    }

Min ():V erdiğimiz iki vektörün x,y,z bileşenlerinden en küçük değerleri alarak bize yeni bir Vector3 değişkeni oluşturur.

    //Verilen iki vektör değişkenin en küçük bileşen değerlerini alarak
    //yeni bir vektor oluşturur;
    void Start () {
        Vector3 vektor1 = new Vector3 (15, -3, 5);
        Vector3 vektor2 = new Vector3 (3, -1, 7);
        Vector3 enKucukDegerler = Vector3.Min (vektor1, vektor2);
        Debug.Log (enKucukDegerler);
    }

MoveTowards (): Başlangıç ve bitiş noktalarını verdiğimiz ve adım adım başlangıçtan bitişe hareket etmemizi sağlayan fonksiyondur. Daha yumuşak ve kontrollü bir hareket elde etmemizi sağlar.

    //basit bir nöbet sistemi olarak kullanabilirsiniz
    //obje belirtilen nöbet noktaları arasında sürekli olarak sırayla dolaşacaktır 
    float hiz = 5f;
    int nobetNoktasiID = 0;
    //4 nöbet noktası ekler
    //ayrıca inspector üzerinde değiştirip yenilerini ekleyebilirsiniz
    [SerializeField]
    Vector3[] nobekNoktalari = new Vector3[] {
        new Vector3 (0, 15, 15),
        new Vector3 (0, -15, 15),
        new Vector3 (0, -15, -15),
        new Vector3 (0, 15, -15),
    };
    void Start () {
        //objeyi ilk nöbet noktasında başlatır
        transform.position = nobekNoktalari[0];
        nobetNoktasiID = 1;
    }
    //iki konum arasında obje hareketini tekrar etmesini sağlayabiliriz
    void Update () {
        float adım = hiz * Time.deltaTime;
        // seçili olan nöbet noktasına adım adım ilerlememizi sağlar
        transform.position = Vector3.MoveTowards (transform.position, nobekNoktalari[nobetNoktasiID], adım);
        //eğer nöbet noktasını yaklaştıysak zıt yönde olacak şekilde tekrar güncelliyoruz
        if (Vector3.Distance (transform.position, nobekNoktalari[nobetNoktasiID]) < .1f) {
            //bölümden kalan sayesiyle sürekli döngü halinde hareket etmesini sağlayabiliriz
            nobetNoktasiID = (nobetNoktasiID + 1) % nobekNoktalari.Length;
            Debug.Log ("Yeni nöbet noktası id: " + nobetNoktasiID + " konum: " + nobekNoktalari[nobetNoktasiID]);
        }
    }

Normalize (): Vektör değişkenini 1 birimlik uzunluğa sahip olacak şekilde x,y,z bileşenlerini değiştirir. normalized özelliğinden farklı olarak bu değişken üzerinde değişiklik yapmaktadır. Eğer değişken değerinin aynı kalmasını istiyorsanız ve normalleştirilmiş haline ihtiyacınız varsa normalized özelliğini kullanmak daha doğru olacaktır.

    void Start () {
        Vector3 vektor = new Vector3 (3, 4, 5);
        Debug.Log ("Asıl Vektor Uzunluğu: " + vektor.magnitude);
        Vector3.Normalize (vektor);
        Debug.Log ("Normalize Fonksiyonu Ardından Uzunluk:" + vektor.normalized);
    }

OrthoNormalize (): Verilen vektörleri normalleştirir ve birbirine dik hale getirir.

    void Start () {
        ilkVector = new Vector3 (15, 3, 0);
        ikinciVektor = new Vector3 (3, 4, 5);
        ucuncuVektor = new Vector3 (4, 5, 6);

        ilkVectorOrj = ilkVector;
        ikinciVektorOrj = ikinciVektor;
        ucuncuVektorOrj = ucuncuVektor;
        Vector3.OrthoNormalize (ref ilkVector, ref ikinciVektor, ref ucuncuVektor);
    }

    void Update () {
        //saniyede 1 sırayla kullanılan vektörlerin orjinallerini
        // ve OrthoNormalize ray çizerek gözlemleyebilirsiniz
        if (Time.time % 2 < 1) {
            Debug.DrawRay (Vector3.zero, ilkVector, Color.red);
            Debug.DrawRay (Vector3.zero, ikinciVektor, Color.blue);
            Debug.DrawRay (Vector3.zero, ucuncuVektor, Color.green);
        } else {
            Debug.DrawRay (Vector3.zero, ilkVectorOrj, Color.black);
            Debug.DrawRay (Vector3.zero, ikinciVektorOrj, Color.white);
            Debug.DrawRay (Vector3.zero, ucuncuVektorOrj, Color.gray);
        }
    }

Project (): Bir vektörün başka bir vektör üzerine izdüşümünü elde etmemizi sağlar. Bunu bir nesnenin yere düşen gölgesini elde etmek olarak da düşünebiliriz. İki değişken alır, gölge örneğini düşünürsek ilk değişken gölgeye sahip olacak nesne, ikinci değişken zemin, bize döndürdüğü değer de ilk vektör değişkeninin ikinci vektör değişkeni üzerindeki gölgesi, izdüşümü olacaktır.

    void Start () {
        Vector3 vektor = new Vector3 (3, 14, 7);
        //Vektörün kendisi
        Debug.DrawRay (Vector3.zero, vektor, Color.white, Mathf.Infinity);

        //X eksenine izdüşümü
        Debug.DrawRay (Vector3.zero, Vector3.Project (vektor, Vector3.right), Color.red, Mathf.Infinity);
        //Y eksenine izdüşümü
        Debug.DrawRay (Vector3.zero, Vector3.Project (vektor, Vector3.up), Color.green, Mathf.Infinity);
        //Z eksenine izdüşümü
        Debug.DrawRay (Vector3.zero, Vector3.Project (vektor, Vector3.forward), Color.blue, Mathf.Infinity);

        // ya da eksenler dışında direkt bir örnek kullanalım
        // (1,1,1) güzel bir değer olabilir. Yorum satırlarını silmeyi unutmayın
        //Vector3 izdusumEkseni = new Vector3 (1, 1, 1);
        //izdüşümü
        //Debug.DrawRay (Vector3.zero, Vector3.Project (vektor, izdusumEkseni), Color.red, Mathf.Infinity);
    }

ProjectOnPlane (): Project gibi çalışır, ancak ikinci bir vektör yerine, bir normal vektör değeri alır. Burada kastedilen normal ise, bir yüzeye tam olarak dik olan vektör manasındadır. Yani tam olarak bir yüzeye izdüşümünü elde etmek için kullanabileceğimiz bir fonksiyondur.

    //0,0,0 noktaında bir plane objesi oluşturup bu alana atayın
    [SerializeField]
    Transform planeObjesi;
    //inspector ekranında vektör değerini değiştirebilirsiniz
    [SerializeField]
    Vector3 vektor = new Vector3 (3, 4, 5);

    Vector3 projectOnPlane;

    // Çalıştırdıktan sonra hem vektor değeriyle
    // hem de plane objesinin açısıyla oynayıp gözlemlemenizi öneririm 
    void Update () {
        //plane objesinde yüzeyin normali, yani yüzeye dik olan değeri transform.up özelliği ile kolayca elde edebiliriz
        //ilk değişken vektörün kendisi, ikinci değişken de normal vektör
        projectOnPlane = Vector3.ProjectOnPlane (vektor, planeObjesi.up);
        //plane üzerine iz düşüm 
        Debug.DrawRay (Vector3.zero, projectOnPlane, Color.green);
        //orjinal vektör
        Debug.DrawRay (Vector3.zero, vektor, Color.red);
    }

Reflect (): Bir Vector3 değişkenin, aynı herhangi bir nesnenin bir aynada sahip olduğu yansıması gibi, bir normal ekseni kullanılarak yansıması elde edilmesini sağlayan fonksiyondur. İlk değişkeni yanstılacak orijinal obje, diğer değişken de yansıtma için kullanılacak Vektor3 tipindeki değişkendir.

    public Transform ilkNesne;
    public Transform yansitilacakNesne;

    //çalıştırma esnasında ilkNesne'ye atadığınız değişkenin konumunu
    //inspector veya scene paneli üzerinden değiştirdiğinizde
    //yansitilacak nesne de hareket edecek, aynadaki bir yansıma gibi davranacaktır.
    void Update () {
        //Z eksenini kullanarak aynalama, yansıma efekti oluşturup
        //yansitilacak nesnenin pozisyonunu belirliyoruz.
        // ikinci değerde farklı vector3 değerleri vererek değişiklikler yapıp gözlemleyebilirsiniz
        yansitilacakNesne.position = Vector3.Reflect (ilkNesne.position, Vector3.right);
    }

RotateTowards ():Aynı MoveTowards fonksiyonunda olduğu gibi, bir vektörden diğerine yumuşak ve kontrollü şekilde geçiş yapmamızı sağlar ancak burada konum yerine yön değişimi yapılmaktadır.

Scale (): 2 Vector3 tipinde değişkeni çarpmamızı sağlar. Burada çarpma işlemi x,y,z bileşenlerinin birbiri arasında olmaktadır. Vector3 tipinde yeni bir değişken elde etmemizi sağlar.

    void Start () {
        Vector3 a = new Vector3 (3, 1, 6);
        Vector3 b = new Vector3 (3, 4, 2);
        Debug.Log (Vector3.Scale (a, b));
    }

SignedAngle (): Angle fonksiyonu gibi iki vektör arasındaki açıyı elde etmemizi sağlar. Ancak farklı olarak bu fonksiyon ile 0 ile 180 arasında değil -180 ile 180 arasındaki açı bilgisini elde edebiliriz.

    [SerializeField]
    Transform hedef;
    //verilen hedefin belilri bir offsete göre sağda veya solda olduğunu belirtir
    void Update () {
        Vector3 hedefYonu = hedef.position - transform.position;
        //Vector3.up kullanarak y eksenin temel alıp bu eksen üzerindeki açıyı elde ediyoruz
        float angle = Vector3.SignedAngle (hedefYonu, transform.forward, Vector3.up);
        if (angle > 5f) {
            Debug.Log ("Hedef Sağda");
        } else if (angle < -5f) {
            Debug.Log ("Hedef Solda");
        } else {
            Debug.Log ("Hedef Önünde");
        }
    }

Slerp (): Lerp fonksiyonu gibi çalışır ancak burada dümdüz bir hat üzerinde ilerlemek yerine izlenecek yol bir kürenin üzerinden ilerleniyormuş gibi olacaktır. Örnek vermek gerekirse, kuzey kutbundan güney kutbuna normal şartlarda dünyanın içinden geçip gidemeyiz, yüzeyinden dolanmamız gerekir. Bu fonksiyon sayesinde bu küresel hareketi sağlayabiliriz. Lerp fonksiyonunda olduğu gibi vereceğimiz oran değeri 0-1 arasında olmalıdır.

    //basit bir gün doğumu-batımı hareketi sağlıyoruz
    // iki tane boş obje oluşturup birini x eksenin -15 diğerini de 15 konumuna getirin ve bu alanlara atayın
    public Transform gunDogumu;
    public Transform gunBatimi;

    // Gün süresi saniye cinsinden
    public float gunSuresi = 15f;

    // başlangıç zamanı
    private float baslangic;

    Vector3 merkez;

    void Start () {
        // Başlangıç değerini atıyoruz
        baslangic = Time.time;
        // gundoğumu ve batımı arasındaki orta nokta
    }

    void Update () {
        Vector3 merkez = (gunDogumu.position + gunBatimi.position) * 0.5F;
        // merkezi y ekseninde azaltarak küresel hareketi dikey hale getiriyoruz
        //1'den daha büyük değerler vererek ulaşacağı en yüksek noktayı arttırabilirsiniz.
        merkez -= new Vector3 (0, 1, 0);

        // varolan merkezi
        Vector3 gunDogumMerkezi = gunDogumu.position - merkez;
        Vector3 gunBatimiMerkezi = gunBatimi.position - merkez;
        //geçen zaman ile gün süresinin bölümü ile oranı belirliyoruz
        float tamamlananZaman = (Time.time - baslangic) / gunSuresi;
        //günün kaçta kaçı geçtiyse, bu oranı kullanarak iki konum arasında küresel bir hareket sağlıyoruz
        transform.position = Vector3.Slerp (gunDogumMerkezi, gunBatimiMerkezi, tamamlananZaman);
        transform.position += merkez;
    }

SlerpUnclamped (): Slerp gibi çalışır ancak daha önce de LerpUnclamped değerinde gördüğümüz gibi, iki nokta arasındaki oran 0’dan küçük veya 1’den büyük olabilir. Verdiğimiz noktaların ilerisine ya da gerisine bu küresel hareketi koruyarak ulaşabiliriz. Bir önceki örnekte Slerp Yerine SlerpUnclamped kullanarak bu dairesel hareketi elde edebilirsiniz.

SmoothDamp (): Verilen vektor değerine aniden erişmek yerine, yumuşatarak erişmemizi sağlayan bir fonksiyondur. En basit kullanım örneği ise bir objenin başka bir objeyi yumuşatılmış, anında kendini ışınlamadan takip etmesi işlemidir.

    public Transform hedef;
    public float yumusatmaCarpani = 0.3F;
    private Vector3 velocity = Vector3.zero;

    void Update () {
        // Takip için araya belirli bir mesafe koyarak hedef konumumuzu belirliyoruz
        Vector3 hedefPozisyon = hedef.TransformPoint (new Vector3 (0, 5, -10));

        // Objenin pozisyonunu hedef pozisyona yumuşatarak erişerek güncelliyoruz.
        transform.position = Vector3.SmoothDamp (transform.position, hedefPozisyon, ref velocity, yumusatmaCarpani);
    }

Böylelikle Vector3 Nedir ve bu değişken tipiyle kullanabileceğimiz metodlar ve değişkenlere göz atmış olduk. Yanılmıyorsam 1-2 adet metoda değinmeden geçtim, bazılarınız farketmişsinizdir. Bu pas geçtiğim fonksiyonlar ciddi anlamda ileri seviye ve kullanımına dair bir örnek yapmak bile yazının tamamını çok fazla kaplayacağını düşünüyorum. Belki ileride onlara da dair de örnekler oluşturabiliriz. Şimdilik bu şekilde yazımızı tamamlayalım. Yeni yazılarda görüşmek dileğiyle, kendinize iyi bakın.

CEVAP VER

Buraya yorumunuzu ekleyin
Buraya adınızı girin