Unity Animation Curve ile Değişimi Kontrol Etmek belki de hiç düşünmeyeceğiniz şekilde mümkün ve kolay. Burada değişimden kastım, bir değişkene verdiğimiz değerin, sabit şekilde değişmesi yerine, başlangıç, bitişte veya bunların arasında farklı hızlarda değişim göstermesi. Objenizi bir noktadan belirli bir noktaya taşırken, sabit hızla ilerlemesi her zaman isteyeceğimiz bir şey olmayabilir. Kimi zaman yavaşça ilerleyip sonrasında hızlanmasını veya tam tersi, ilk başta hızlıca ilerleyip sona doğru yaklaştıkça yavaşlamasını isteyebilirsiniz. Veya bir konuma gidip tekrar geri gelmesini. Kod ile uğraşmadan bu ayarlamaları Unity Animation Curve ile yapmak gayet mümkün bir durum.

Öncelikle, Unity Animation Curve nedir ondan bir bahsetmekte yarar var. Animation Curve aslında Unity’de oluşturduğumuz animasyonlarda en sık kullanılan, değiştirdiğimiz değerleri gözlemleyebildiğimiz ve kontrol edebildiğimiz bir değişken tipi diyebiliriz. Animasyon penceresinde uğraştıysanız illa ki denk geldiğinizi düşünüyorum, ancak bilmeyenler için bir gösterelim.

Animasyon Penceresinde Animation Curve
Animasyon Penceresinde Animation Curve

Animasyonlar içerisinde yatay (x) eksen zamanı, kare sayısını gösterirken, dikey (y) değeri göstermektedir. Az çok matematik derslerinden hatırlarsınız ki, bu resmen bir fonksiyon ve onun grafiği gibi aslında. En basit haliyle, y=f(x) şeklinde gördüğümüz fonksiyonlarda olduğu gibi, x değerini verip y ile sonucu elde ediyoruz. Animasyonlar da aslında bu şekilde çalışıyor, x zamanında y değeri ne olacak, bunun verisini tutuyor. Ancak ben bu yazıda Animasyon penceresinde değil de, bir script içerisinde bir değişken olarak Unity Animation Curve İle Değişimi Kontrol Etmek nasıl olur, buna değineceğim. Eğer açtıysanız animasyon penceresini kapatabilirsiniz, ona bu yazıda ihtiyacımız yok 🙂

Kodumuzda bundan yararlanırken, bir arayüz sayesinde bu grafiği düzenleyebilmemiz nedeniyle, matematiksel hesaplamalar ile çok fazla uğraşmamıza gerek kalmayacak. Kontrol edebilmek için sadece birazcık mantığını oturtmamız yeterli olacaktır. Bunu da oluşturduğumuz grafiği iyice gözlemleyerek yapabiliriz. Bu yapacağımız değişimi kontrol etme olayı için kullanılan bir terim de aslında Easing. Hatta DOTween içerisinde de bu fonksiyonlar bize sunuluyor. DOTween paketini kullanıyorsanız, SetEase fonksiyonu ile bu kontrolü sağlayabilirsiniz. Kendi dokümanlarında ilgili fonksiyonu bulmanız mümkün. Ayrıca çoğunu çevirdiğimiz bir DOTween dokümanı da mevcut. 

Dediğim gibi, matematiksel hesaplamalar kısmına, en azından bu yazıda, girmeyeceğim. Ancak internette ufak bir araştırma ile matematik fonksiyonlarına erişmeniz mümkün. En güzel gösterimlerden biri de https://easings.net/ içerisinde. Farklı Ease tiplerine tıklayıp incelediğinizde, en altta TypeScript ile yazılmış matematik fonksiyonlarını da görebilirsiniz. Kod ile nasıl bunu sağlarım diyorsanız da, verdiğim linkten gidip bu fonksiyonları inceleyebilirsiniz. Bu site temelde web için örneklere sahip olduğundan TypeScript dili kullanılmış. Ancak basitçe C# diline çevirebileceğinizi düşünüyorum.

Unity Animation Curve ile Hareket Değişimi

Şimdi basit bir örnek olarak Unity Animation Curve ile Değişimi Kontrol Etmek nasıl gerçekleştirilebilir, bunu adım adım gerçekleştirelim. Öncelikle, varolan pozisyondan verilen pozisyona giden bir objemiz olsun. Bir küp nesnesi oluşturup aşağıdaki kodu oluşturup objenize atayın. Eğer kodda hareketle ilgili anlamadığınız kısımlar varsa Unity Vector3 Nedir? yazımıza göz atmanızda da fayda var. Sadece ufak bir not olarak şunu belirteyim, Lerp fonksiyonunda, verdiğimiz 2 vector3 konumu arasında hareketi sağlayabiliyoruz. Bunu da son değişken olarak verdiğimiz float tipindeki değer ile yapıyoruz. 0 verirsek ilk konum, 1 verirsek 2. konumu bize döndürecektir. 0,5 verirsek de tam ortalarında bir konum elde edeceğiz.

using System.Collections;
using UnityEngine;

public class AnimationCurveMove : MonoBehaviour {

    Vector3 baslangicKonum;

    [SerializeField]
    Vector3 hedefKonum;

    void Start () {
        baslangicKonum = transform.position;
    }

    void Update () {
        if (Input.GetKeyDown (KeyCode.Space)) {
            StartCoroutine (Hareket ());
        }
    }

    IEnumerator Hareket () {
        //zaman durumunu tuttacağımız değişken.
        float zaman = 0;
        //zaman 1 değeri ve altında olduğu sürece hareketi gerçekleştiriyoruz.
        while (zaman <= 1) {
            //başlangic ve hedef değerlerini toplama sebebim, verdiğimiz hedefi varolan pozisyona göre hesaplamasını istememden kaynaklı
            transform.position = Vector3.Lerp (baslangicKonum, baslangicKonum + hedefKonum, zaman);
            zaman += Time.deltaTime;
            yield return new WaitForEndOfFrame ();
        }
    }
}

Çalıştırıp space tuşuna basarak hareketini gözlemleyin. Baya sıkıcı bir şekilde sabit bir hızda ilerliyor değil mi? Bunu birazcık değiştirelim şimdi, önce yavaşlayarak hızlanma durumunu oluşturacağız, ardından tam tersi, önce hızlı sonra yavaş. Ardından da 3. örnek olarak objenin konuma gidip geri gelmesini sağlayacağız. Tabii ki ilk yapmamız gereken Unity Animation Curve tipinde bir değişken yaratmak. Start fonksiyonu öncesinde değişkenlerin olduğu kısıma aşağıdaki kodu ekleyin.

//Animation Curve Değişkeni
[SerializeField]
AnimationCurve animCurve;

Daha sonrasında editor kısmına tekrar geri dönerseniz, küp objemizde kodumuzun değişkenlerinin arasında bu yarattığımız değişken de gözüküyor. Ancak farklı bir yapıya sahip gibi, hiç beklemeden merakınızı giderelim. O alana tıklayın. Karşınıza şöyle bir pencere açılacaktır.

Unity Animation Curve Paneli
Unity Animation Curve Paneli

Bomboş olması bir garip di mi? Önce bunu bir düzeltelim. Görselde gördüğünüz kırmızı çizgiyle çekilmiş olana tıklamanızı istiyorum. Bu sayede hazır bir grafik kullanmış olacağız. Dikkatinizden kaçtıysa belirteyim, çizginin uçlarında 2 adet nokta oluşturuldu aynı zamanda. Bu noktalar aracılığıyla aslında grafik oluşuyor, biz grafiği kontrol edebiliyoruz. Noktaları isterseniz sürükleyerek isterseniz de sağ tıklayıp “Edit Key” diyerek noktanın değerlerini, konumunu değiştirmeniz mümkün. Detaylı olarak değiştirmeyi yazının devamında göstereceğim, o yüzden şimdilik böyle kalsın.

Öncesinde bahsettiğim yatay ve dikey eksenlerin varlığını tekrar hatırlatmakta fayda var. Unutmayın, yatay bizim verdiğimiz değer, dikey ise elde edeceğimiz değer olacak. İşte buradan alacağımız değeri Lerp fonksiyonunda kullanacağız. Bunun için de yapmanız gereken kodumuza geri dönüp, Vector3.Lerp fonksiyonunun olduğu satırı, aşağıdaki satır ile değiştirmek.

transform.position = Vector3.Lerp (baslangicKonum, baslangicKonum + hedefKonum, animCurve.Evaluate (zaman));

Animation Curve ile kullandığımız Evaluate isimli method, aynı bahsettiğim matematik fonksiyonlarındaki gibi, verdiğimiz değere karşılık fonksiyon sonucunu bize veriyor. Bu durumda da  Animation Curve üzerinden bu değeri bize verecek. Şimdi hazır seçili grafiğin hareketi nasıl değiştirdiğini gözlemlemenizi istiyorum. Çalıştırıp kontrol edin. Hatta çalışırken bir yandan Animation Curve penceresi açık da kalabilir, bu sayede hareketi ve grafiği yorumlamanız daha kolay olacaktır. 

İlk hazır grafiği kullandıktan ve gözlemledikten sonra, bu aşamada topu birazcık size bırakıyorum ve geri kalanları da gözlemlemenizi istiyorum. Grafik değiştikçe hareket değişimi nasıl oluyor, grafikteki hangi özellikler hareketi hızlandırıyor? Bunun üzerine birazcık düşünüp yazıya öyle devam etmenizi istiyorum.

Genel mantığı anladığınızı düşünüyorum ancak iyice oturtmakta fayda var. Bizim bu grafiğe verdiğimiz değer, bu durumda aslında zaman değeri. Geriya aldığımız, bize dönen değer ise yolun hangi kısmında olacağımız değeri. Şu anki kodumuzda bu şekilde kullanıyoruz yani. Şimdi ilk başta tıklamanızı istediğim grafiği ele alalım. 

Dümdüz bir hareket var, herhangi bir noktada çizginin eğimi değişmiyor, ne azalma ne artma var. Bu sürekli, linear bir hareket elde etmemizi sağlıyor aslında. Eğim süre boyunca aynı kaldığı için, değişim de aynı kalmakta. Artış miktarı hiç değişmiyor bu süre içerisinde. Şimdi o hazır grafiğin sağındaki grafiğe tıklayıp seçmenizi istiyorum. 

Yolun yarısına gelmek için 0,7 saniye harcamamız gerekiyor, sonrasında kalan yarımı tamamlamak ve son noktaya gelmek için ise 0,3 saniye. Baktığımızda gidilen mesafe aynı, ama mesafeyi tamamlama süresi farklı oluyor. E haliyle, hız da buna göre değişmiş oluyor.  Bahsettiğim değerleri de grafikten nasıl çıkardığımızı aşağıdaki görselden görebilirsiniz.

Unity Animation Curve Grafik Gözlemi 1
Unity Animation Curve Grafik Gözlemi 1

Yapabileceğimiz bir diğer çıkarım ise, grafikteki yön değişimi. Örneğin bahsettiğim gibi, dikeyde 0,5 değerine erişene kadar grafikteki artış yavaş, nispeten yatay bir şekilde ilerliyor. Ancak dikeydeki 0,5 – 1 değerleri arasındaki artış daha fazla, grafik dikleşmiş halde. Bunu gözlemlemek adına ufak kesitler alarak incelemek de faydalı aslında. Bu çıkarımı yaparken de aşağıdaki gibi, ufak kesitler alarak aynı zaman aralığında dikeydeki değişimleri incelemek mümkün.

Unity Animation Curve Grafik Gözlemi 2
Unity Animation Curve Grafik Gözlemi 2

Unity Animation Curve ile Grafik Oluşturmak

Peki Unity Animation Curve ile Grafik Oluşturmak için noktaları nasıl kullanacağız? Açıkçası gayet basit. Eğer grafiğin, çizginin üzerine çift tıklarsanız, tam o konumda yeni bir nokta yaratacaktır. Aynı şekilde, grafiğin en sağı veya en solunda, yani grafiğin dışında kalan alanlara tıklayarak yeni noktalara oluşturabilirsiniz. Tıkladığınız yerdeki değerleri beğenmediniz veya konumu değiştirmek istiyorsanız, isterseniz noktayı tutup sürükleyere konumu değiştirebilirsiniz. Veya isterseniz de sağ tıklayıp “Edit Key” diyerek noktanın değerlerini değiştirmeniz mümkün. Aşağıdaki görselde sırasıyla, varolan grafiğe yeni bir nokta ekliyorum, sonrasında edit seçeneği ile değerlerini değiştiriyorum. Burada yazan time değişkeni yatayı, value değişkeni dikeyi belirtmektedir. 

Bunu yaptıktan sonra, noktanın bu grafiğe nasıl etki edeceğine de karar verebiliriz. Öncelikle noktaya tıklayarak seçili hale getirmeniz gerekiyor. Ufak bir bilgilendirme olarak da şunu belirteyim, dikdörtgen seçimi yaparak hem tekil hem çoğul nokta seçimini yapabilirsiniz. Bu sayede de toplu hareket ettirme gibi işlemleri gerçekleştirebilirsiniz.

Bir nokta seçili iken, öncesindeki ve/veya sonrasındaki nokta ile arasındaki çizgiyi manipüle etmenizi sağlayan kollar bulundurur. Bunları tutup aşağı yukarı eğerek, noktanın grafiğe olan etkisini kontrol edebilirsiniz. 

İsterseniz sağ tıkladığınızda beliren otomatik ayarlamaları kullanabilirsiniz. Bu ayarlar şunlardır;

  • Clamped Auto: Eklediğimiz noktanın etkisini yumuşatır ve öncesinde- sonrasında bulunan noktalar arasında sert-düz çizgi yerine kıvrımlı bir çizgiyi otomatik olarak oluşturur. Kolları tutup çekerek değiştirirseniz ve sonrasında memnun kalmazsanız, sağ tıklayıp bu seçenekle otomatik olarak şekillendirebilirsiniz. 
  • Auto: Eski sürümlerde varolan bu yapı Clamped Auto gibi çalışır. Bunun yerine Clamped Auto kullanmakta fayda var. 
  • Free Smooth: Kolları manipüle ettiğinizde bu seçeneği aslında aktif etmiş oluyorsunuz. Ancak, birini manipüle ettiğinizde, o yumuşak geçişi sağlamak adına diğer kol da yeniden konumlanacak ve noktanın oluşturduğu etkinin yumuşaklığını koruyacaktır.
  • Flat: Bu seçeneği seçtiğinizde, kolların ikisi de yatay eksene paralel olacaktır, düz bir hal alacaktır. 
  • Broken: Bu seçenek aracılığıyla da, kolları ayrı ayrı kontrol etmeniz mümkün. Bu sayede 2 kol varsa, öncesi ve sonrasında noktalar bulunuyorsa, yumuşatmaksızın grafiğe etkisini kontrol altına alabilirsiniz. 

Bunlar dışında ayrıca, isterseniz bahsettiğim kollara farklı ayarlamalar yapmanız da mümkün. Yine sağ tıkladığınızda “Left Tangent” (sol)  ve “Right Tangent” (sağ) ve “Both Tangent” (her ikisi de) seçeneklerini göreceksiniz. Bunlar altında bulunan seçeneklerle, ayrı ayrı kontroller sağlamanız mümkün. Kollara ait bu seçenekler ise şu şekilde;

  • Free: Belirtilen kolun diğer koldan bağımsız şekilde hareket ettirilebilmesini sağlar.
  • Linear: Kolun oluşturacağı çizginin dümdüz olmasını sağlar. Hiçbir eğilme, yumuşatma uygulatmadan hedefteki noktaya doğru düz bir çizgi oluşturur.
  • Constant: Arada geçişi sağlayan bir çizgi oluşturmak yerine, ilgili noktadan, bu noktaya aniden geçiş yapan bir grafik oluşturmamızı sağlar. 
  • Weighted: Bu seçenek açılıp kapatılabilir bir seçenektir. Free seçeneği aktif iken, kolun uzunluğunu da kontrol etmemizi sağlar. Böylece grafik üzerinde daha fazla kontrole sahip olabiliriz. 

Unity Animation Curve ile Gitgel Grafiği

Şimdi gelelim Unity Animation Curve ile Gitgel Grafiği yapmaya. Şu satırlara kadar okuduğunuz haliyle, grafiği nasıl yorumlayacağınızı ve şekillendireceğinizi temel olarak öğrendiniz. Dikeyde 0’dan başlayıp 1 değerine gelince, şu anki Lerp komutumuz sayesinde ilk pozisyondan, son pozisyona geliyoruz. Bunu da biliyorsunuz. Peki baştan başlayıp, sona gidip tekrar başa dönmesi için ne yapabiliriz? Başlangıç 0, bitiş 1, ve tekrar başlangıç 0.. Bu yapıyı oluşturabilmemiz gerekiyor, yani en az 3 nokta lazım bize. İsterseniz varolan bir grafik üzerinden, isterseniz de boş bir grafik üzerinden 3 nokta oluşturalım. Yataydaki değerleri 0, 0,5 ve 1 olacak. Dikeydeki değerleri ise 0 (başlangıç), 1 (bitiş), 0 (başlangıç) olacak. Yazı hali karmaşık geldiyse, aşağıdaki görselden nasıl oluşturabileceğimizi ve grafiğin son halini görebilirsiniz.

Unity Animation Curve ile Gitgel Grafiği
Unity Animation Curve ile Gitgel Grafiği

Bu grafiği oluşturduktan sonra çalıştırırsanız, objemiz başlangıçtan bitişe gidecek ve tekrar geri gelecektir. Grafik üzerinde bu 3 noktanın dikey konumları şu haliyle kaldığı sürece, bu hareketi sağlayabilirsiniz. Bu konumları korurken, daha önce bahsettiğim gibi noktalar arasındaki çizgileri manipüle etmeniz de mümkün. Ortada bulunan noktayı yatayda hareket ettirerek veya noktalara bağlı kolları kontrol ederek bunu sağlayabileceğinizi tekrar hatırlatayım. Bitişe giderken çok hızlı bir şekilde gitmesini sağlayıp, dönüşte çok yavaş ilerletebilirsiniz. Artık gerisi hayal gücünüze, size kalmış.

Ancak, az başlangıçtaki harekete göre, 2 kat daha hızlı bir hareket gerçekleşiyor gibi. Bunun sebebi verdiğimiz 1 saniyelik süre boyunca artık 2 kat mesafe ilerleniyor. İstediğiniz süre boyunca hareket etmesini sağlamak için, while döngüsünde kullandığımız 1 yerine, float tipinde bir değişken tanımlayabiliriz. Tabii ki sonrasında, yol durumunu da bu süreye bölmemiz gerekiyor ki, yine 0-1 arasında değer elde edelim. Böylece Evaluate içerisine 0-1 arasında bir değer verebilmiş olacağız. Kodun son hali aşağıdaki gibi olacaktır. Ha tabii ki, ufak bir kontrol de ekledim, böylece hareket halindeyken space tuşuna basıla bile hareket komutu çalışmıyor. İstemediğimiz bir durum olmasından kaçınabiliyoruz.

using System.Collections;
using UnityEngine;

public class AnimationCurveMove : MonoBehaviour {

    Vector3 baslangicKonum;

    [SerializeField]
    Vector3 hedefKonum;

    [SerializeField]
    AnimationCurve animCurve;

    [SerializeField]
    float toplamZaman = 2f;

    bool hareketEdiyor = false;

    void Start () {
        baslangicKonum = transform.position;
    }

    void Update () {
        //Space tuşuna basıldıysa ve hareketEdiyor false değere sahip ise
        if (Input.GetKeyDown (KeyCode.Space) && !hareketEdiyor) {
            StartCoroutine (Hareket ());
        }
    }

    IEnumerator Hareket () {
        hareketEdiyor = true;
        //zaman durumunu tuttacağımız değişken.
        float zaman = 0;
        //zaman,  toplamZaman değeri ve altında olduğu sürece hareketi gerçekleştiriyoruz.
        while (zaman <= toplamZaman) {
            //başlangic ve hedef değerlerini toplama sebebim, verdiğimiz hedefi varolan pozisyona göre hesaplamasını istememden kaynaklı
            transform.position = Vector3.Lerp (baslangicKonum, baslangicKonum + hedefKonum, animCurve.Evaluate (zaman / toplamZaman));
            zaman += Time.deltaTime;
            yield return new WaitForEndOfFrame ();
        }
        hareketEdiyor = false;
    }
}

Bu haliyle artık Unity Animation Curve ile Değişimi Kontrol Etmek nasıl gerçekleştirilir için güzel bir örnek oluşturduğumu düşünüyorum sizler için. Lerp fonksiyonu sadece bir örnek, bununla kısıtlı değilsiniz. Evaluate komutunu direkt olarak değişkenlere değer atamak için de kullanabilirsiniz. Tamamen hayalgücünüze kalmış, deneyin, yanılın, uğraşın ve öğrenin. Umarım faydalı olmuştur bu yazı sizler için, ben yazarken keyif aldım açıkçası. Yeni yazılarda görüşmek dileğiyle.

CEVAP VER

Buraya yorumunuzu ekleyin
Buraya adınızı girin