Unity Time sınıfı, Unity içerisinde zaman hakkında bilgi edinmemizi sağlayan sınıftır. Unity Time sınıfı aracılığıyla oyun içerisindeki zamanı yavaşlatıp hızlandırabilir, geçen zamana göre işlemler gerçekleşmesini sağlayabiliriz. Time sınıfı özellikle Transform ile yaptığımız hareketlerde, saniyedeki kare sayısı(fps) etkisinden kurtularak, gerçek zamana göre işlemler gerçekleştirmemize de imkan sağlayacaktır.

Özellikle bir objeyi hareket ettirmek istediğinizde veya zamanla gerçekleşecek haşka herhangi bir işlem yaptığımızda deltaTime özelliğinden yararlandığımızı farklı örneklerde görmüşsünüzdür. Ancak Time sınıfının bize sundukları bununla sınırlı kalmıyor. Yazının devamında bunları sıralayıp olabildiğince kullanımlarına dair örnekler de oluşturduğumu göreceksiniz. Ancak daha öncesinde, şayet Unity üzerinde C# ile nasıl kod oluşturacağınız ve GameObject üzerine atamaya yapacağınızı bilmiyorsanız, “Unity C# Temel Dersi ve Fizik ile Basit Hareket” yazımıza göz atabilirsiniz.

Unity Time Sınıfı ile Kullanılabilecek Kodlar

Unity Time Sınıfı ile Kullanılabilecek Kodlar tamamıyla zaman hakkında değer okuma veya bir iki tanesinde değer değiştirme, yani yazma amacıyla kullanılmakta. Herhangi bir fonksiyon içermez, tamamen özelliklerden, properties yapılarından oluşmaktadır. Şimdi sırasıyla kullanım örnekleriyle beraber bunları ele alalım.

captureDeltaTime: Oyun içerisinde ekran görüntüleri almamıza yardımcı olmasıyla oynatma zamanını yavaşlatıp hızlandırmamıza imkan veren özellik.Bu sayede karelerin arasına istediğimiz kadar zaman koyabiliyoruz. Unity’nin belirttiği üzere özellikle görsellerden bir gif veya video oluşturmak istiyorsanız işinize yarayacak bir yöntemdir.

using UnityEngine;

public class EkranGoruntusuYakala: MonoBehaviour {

    public string klasorIsmi = "EkranGoruntuleri";
    public int kareSayisi = 25;
    void Start () {
        // Oynatma süresinde kullanılacak, kareler arası geçiş süresini belirliyoruz.
        Time.captureDeltaTime = 1.0f / kareSayisi;

        // Klasörü oluştur
        System.IO.Directory.CreateDirectory (klasorIsmi);
    }

    void Update () {
        // Ekran görüntüsü ismini belirliyoruz, örnek isim formatı'0005 shot.png'
        string dosyaYolu = string.Format ("{0}/{1:D04} kare.png", klasorIsmi, Time.frameCount);

        // Ekran görüntüsünü alıp, belirlediğimiz dosya yolunda dosyayı oluşturuyoruz.
        ScreenCapture.CaptureScreenshot (dosyaYolu);
    }
}

captureFramerate: captureDeltaTime özelliği gibi çalışır, ancak zaman aralığın vermek yerine saniyede elde etmek istediğiniz kare sayısını bu değere atamamız gerekiyor. Yukarıdaki örneğin aynısının captureFramerate halini görebilirsiniz.

using UnityEngine;

public class EkranGoruntusuYakala: MonoBehaviour {

    public string klasorIsmi = "EkranGoruntuleri";
    public int kareSayisi = 25;
    void Start () {
        // Oynatma süresinde kullanılacak, 1 saniyenin kaç kareden oluşacağını belirliyoruz.
        TTime.captureFramerate = kareSayisi;

        // Klasörü oluştur
        System.IO.Directory.CreateDirectory (klasorIsmi);
    }

    void Update () {
        // Ekran görüntüsü ismini belirliyoruz, örnek isim formatı'0005 shot.png'
        string dosyaYolu = string.Format ("{0}/{1:D04} kare.png", klasorIsmi, Time.frameCount);

        // Ekran görüntüsünü alıp, belirlediğimiz dosya yolunda dosyayı oluşturuyoruz.
        ScreenCapture.CaptureScreenshot (dosyaYolu);
    }
}

deltaTime: Bir önceki kare ile şu anki kare arasındaki zamanı elde etmemizi sağlayan özelliktir. Bu değer aynı zamanda Update fonksiyonlarımızın da hangi zaman aralıklarıyla çalıştığını gösteren bir değerdir. Saniye cinsinden değer döndürür ve sadece değer okuma yapabiliriz. Yani bu değeri değiştiremeyiz.

using UnityEngine;

public class DeltaTimeIleHareket : MonoBehaviour {
    float zamanlayici = 0;

    [SerializeField]
    float beklemeZamani = 1;
    //Update içerisinde deltatime ile zamanı tutarak belirlediğimiz aralıklarla pozisyonu değiştiriyoruz.
    void Update () {
        zamanlayici += Time.deltaTime;
        if (zamanlayici >= beklemeZamani) {
            zamanlayici -= beklemeZamani;
            transform.position += Vector3.forward;
        }
    }
}

fixedDeltaTime: FixedUpdate gibi fonksiyonların kullandığı sabit zaman aralığın değeri. MonoBehaviour içerisinde kullandığımız FixedUpdate dışında, Rigidbody vb fizik hesaplamalarında da bu değer kullanılmaktadır. Saniye cinsinden değer döndüren bu özellik, aynı zamanda değerini değiştirmemize de imkan tanır. Bu sebeple bunun yerine Time.deltaTime kullanmakta yarar vardır, çünkü o daha doğru bir zaman farkı elde etmenizi garanti edecektir.

fixedTime: FixedUpdate fonksiyonlarının tümünün çalışmaya başlamasından itibaren geçen süreyi elde etmemizi sağlar. Saniye cinsinden oyun başlangıcından itibaren geçen zamandır.

fixedUnscaledDeltaTime: Önceki kare ile şu anki kare arasında geçen gerçek zamanı elde etmemizi sağlar. timeScale değerinden etkilenmeyen bir değerdir.

fixedUnscaledTime: Oyun başından beri geçen gerçek zamanı elde etmemizi sağlar, ancak unscaledTime değerinden farklı olarak, FixedUpdate fonksiyonlarının çalışmasının başlamasını bekler. En sondaki örnekte karşılaştırmalarını görebilirsiniz.

frameCount: Toplamda geçmiş kare sayısını elde etmemizi sağlar. Kare sayısının hesaplanmaya başlaması ancak bütün Awake fonskiyonları bittikten sonra gerçekleşecektir. 

inFixedTimeStep: Bu kod çağırıldığında FixedUpdate gibi sabit aralıklı bir fonksiyondan çağırılıp çağırılmadığını elde etmemizi sağlar. Eğer bahsedildiği gibi FixedUpdate vb sabit aralıklı çalışan bir yapı içerisindeysek, true değeri döndürecektir.

using UnityEngine;
[RequireComponent (typeof (Rigidbody))]
public class Jump : MonoBehaviour {

    Rigidbody rigidbody;
    float jumpForce = 5f;

    void Start () {
        rigidbody = GetComponent<Rigidbody> ();
    }
    //test amacıyla DoJump fonksiyonumuzu Update ve FixedUpdate içerisinde çağırıyoruz.
    void Update () {
        if (Input.GetKeyDown (KeyCode.E)) {
            DoJump ();
        }
    }
    void FixedUpdate () {
        if (Input.GetKeyDown (KeyCode.Q)) {
            DoJump ();
        }
    }
    void DoJump () {
        //Rigidbody işlemlerimizin yalnızca FixedUpdate gibi 
        if (Time.inFixedTimeStep) {
            rigidbody.AddForce (Vector3.up * jumpForce, ForceMode.Impulse);
        } else {
            Debug.LogWarning ("Jump fonksiyonu sabit aralıklı karelerde (örneğin FixedUpdate) çağırılmalıdır.");
        }
    }
}

maximumDeltaTime: Bir karenin, update işleminin işlem süresinin alabileceği maksimum değeri belirlememizi veya elde etmemizi sağlar. Fizik veya benzeri sabit aralık kullanan sistemler (örneğin FixedUpdate) bu değeri kullanarak işlem sürelerini ayarlayacaklardır. Özellikle Garbage Collector ve fazla işlem gerektiren fizik işlemlerinden kaynaklanan kare sayısı azalmalarını engellemek için kullanılabilir. Unity değer aralığı saniyenin 10’da biri (1/10) ve 3’te biri (1/3) olacak şekilde ayarlanmasını tavsiye etmektedir.

maximumParticleDeltaTime: Particle objelerinin update fonksiyonlarının sürebileceği maksimum değeri elde etmemizi sağlar. Eğer update işlemi bu sürenin üstüne çıkarsa, update işlemleri çoğalarak daha ufak update işlemleri haline dönüşür. Ufak bir değer verildiğinde, particle için daha doğru sonuçlar elde edilse de, iş yükü artacaktır. Büyük değerler verildiğinde ise particle daha az doğruluğa sahip sonuçlar verecektir ama performans artacaktır.

realtimeSinceStartup: Uygulamanın başlatılmasından itibaren geçen geçen gerçek zamanı elde etmemizi sağlar. timeScale değerinden etkilenmez.

smoothDeltaTime: deltaTime ile olduğu gibi, kareler arasında zamanı elde etmemizi sağlar. Ancak, önceki kare arasındaki zaman değerleriyle karşılaştırılması ve buna göre hesaplanması ile daha yumuşak bir değer elde etmemizi sağlar. Aşağıdaki basit tabloda deltaTime ve smoothDeltaTime ile elde edeceğimiz örnek verileri görebilirsiniz. 

deltaTimesmoothDeltaTime
0.250.25
0.250.25
0.250.25
0.95 (+380%)0.4833(+193%)
0.25 (-73%)0.4833
0.250.4833
0.25 0.25   (-51%)
0.250.25
Time.deltaTime ve Time.smoothDeltaTime üzerinden alınacak değerlerin örnek karşılaştırması

time: Oyun çalışmaya başladığı andan itibaren geçen zamanı saniye cinsinden elde etmemizi sağlar.

using UnityEngine;

public class TimeIleDaireselHareket : MonoBehaviour {
    /*Sin ve Cos matematik fonksiyonları aracılığıyla, 
    dairesel hareket sağlıyoruz. 
    */
    void Update () {
        transform.position = new Vector3 (Mathf.Cos (Time.time), Mathf.Sin (Time.time), 0);
    }
}

timeScale: Zaman çarpanı olarak da belirtebileceğimiz bu özellik, oyun içerisinde işlemler gerçekleşirken zamanı nasıl ele alacağını belirlememizi sağlar. En basit örnekle, 0 değerini verirsek oyunda fizik işlemleri, kullanıcıdan veri alma gibi bütün işlemler duracaktır, 2 değerini verirsek de, 2 katı hızında işlemler gerçekleşecektir. Standart haliyle 1 değerine sahiptir.

using UnityEngine;

public class TimeScaleYavaslatma : MonoBehaviour {

    void Update () {
        /*Z tuşuna basılıp bırakılınca timeScale değerini manipule ediyoruz. 
        Bastığımızda yavaşlayacak, bıraktığımızda 1 deeğerine yani eski haline dönecek.
        Bu .5-1 değerlerini aniden atamak yerine yumuşak bir geçiş yapmanız da mümkün.
        Güzel bir alıştırma olur :)
        */
        if (Input.GetKeyDown (KeyCode.Z)) {
            Time.timeScale = .5f;
        }
        if (Input.GetKeyUp (KeyCode.Z)) {
            Time.timeScale = 1;
        }
    }
}

timeSinceLevelLoad: En son sahnenin yüklenme anından itibaren geçen zamanı saniye cinsinden elde etmemizi sağlar.

unscaledDeltaTime: timeScale değerinden etkilenmeyecek şekilde, kareler arasında geçen zamanı elde etmemizi sağlar. Örneğin, timeScale 0 değerine sahipse, deltaTime değerini de 0 alacaktır ancak bu değer kareler arasındaki zamanı elde etmemizi sağlayacaktır. Yani timeScale değerini kullanarak oyundaki işleyişi durdursak bile, unscaledDeltaTime ile kareler arasındaki gerçek zaman değerini saniye cinsinden elde edebiliriz.

unscaledTime: Oyun başlangıcından beri geçen zamanı elde etmemizi sağlar. Yine aynı şekilde, timeScale değerinden etkilenmeyen bir değişkendir. Uygulama başladığından beri geçen gerçek zamanı saniye cinsinden elde etmek için kullanabilirsiniz.

using UnityEngine;

public class TimeKarsilastirma: MonoBehaviour {
    //Ekranda göstereceğimiz verilerin renk ayarını yapıyoruz
    GUIStyle style;
    void Start () {
        style = new GUIStyle ();
        style.normal.textColor = Color.red;
    }
    void Update () {
        /*E tuşuna basılıp bırakılınca timeScale değerini manipule ediyoruz. 
        Bu sayede karşılaştırma yapabiliriz.
        */
        if (Input.GetKeyDown (KeyCode.E)) {
            Time.timeScale = 0;
        }
        if (Input.GetKeyUp (KeyCode.E)) {
            Time.timeScale = 1;
        }
    }

    void OnGUI () {
        //GUI.Label ile istediğimiz içeriği istediğimi konumda ve stilde yazdırıyoruz.
        GUI.Label (new Rect (10, 10, 100, 20), "deltaTime:" + Time.deltaTime, style);
        GUI.Label (new Rect (10, 30, 100, 20), "fixedDeltaTime:" + Time.unscaledDeltaTime, style);
        GUI.Label (new Rect (10, 50, 100, 20), "fixedtime:" + Time.time, style);
        GUI.Label (new Rect (10, 70, 100, 20), "time:" + Time.time, style);
        GUI.Label (new Rect (10, 90, 100, 20), "unscaledDeltaTime:" + Time.unscaledDeltaTime, style);
        GUI.Label (new Rect (10, 110, 100, 20), "fixedUnScaledDeltaTime:" + Time.fixedUnscaledDeltaTime, style);
        GUI.Label (new Rect (10, 130, 100, 20), "fixedUnscaledTime:" + Time.fixedUnscaledTime, style);
        GUI.Label (new Rect (10, 150, 100, 20), "unscaledTime:" + Time.unscaledTime, style);
    }
}

Bu son örnekle beraber aslında farklı zaman özelliklerinin karşılaştırmasını da görebiliyoruz. Yalnızca belirlediğimiz tuşa basarak değil, aynı zamanda editor durdurma (Pause) tuşuna basarak da anlık olarak, özellikle deltaTime tipleri arasındaki farkı görebilirsiniz. Böylelikle bu dokümanı da Türkçeye kazandırmış olduk. Dilerseniz orjinal dokümanı da buraya tıklayarak inceleyebilirsiniz. Faydalı olması dileğiyle, yeni yazılarda görüşmek üzere.

CEVAP VER

Buraya yorumunuzu ekleyin
Buraya adınızı girin