Unity Eğitim
Dersler
Forum Sınav Merkezi Premium 💎
C# Dersleri

Unity'de JsonUtility.ToJson() Kullanımı: Veri Serileştirme Rehberi

Paylaşan: Unity Eğitim 24 December 2025 9 dakika okuma 159 görüntülenme

Unity'de JsonUtility.ToJson() Kullanımı: Veri Serileştirme Rehberi

Unity oyun veya uygulama geliştirirken, verileri kaydetme, yükleme, ağ üzerinden gönderme veya yapılandırma dosyalarını yönetme gibi ihtiyaçlar sıkça karşımıza çıkar. Bu senaryolarda JSON (JavaScript Object Notation) formatı, hafifliği, okunabilirliği ve platform bağımsız yapısı sayesinde oldukça popüler bir tercihtir. Unity, bu ihtiyacı karşılamak için yerleşik bir çözüm sunar: JsonUtility sınıfı. Bu kapsamlı rehberde, JsonUtility.ToJson() metodunu kullanarak C# objelerinizi JSON formatına nasıl dönüştüreceğinizi detaylı bir şekilde inceleyeceğiz. Özellikle Unity JSON Dönüştürme süreçlerini adım adım ele alacağız.

Neden JSON ve Unity'de JsonUtility?

JSON, insan tarafından kolayca okunabilen ve yazılabilen, makineler tarafından ise kolayca ayrıştırılabilen açık standart bir veri değişim formatıdır. Oyun geliştirme bağlamında JSON'u tercih etmenin başlıca nedenleri şunlardır:

  • Okunabilirlik: Düz metin tabanlı olduğu için verileri incelemek ve hata ayıklamak kolaydır.
  • Hafiflik: XML gibi diğer formatlara göre daha az yer kaplar, bu da özellikle mobil platformlarda veya ağ iletişimi sırasında önemlidir.
  • Evrensellik: Neredeyse tüm programlama dilleri ve platformlar tarafından desteklenir.

Unity'nin JsonUtility sınıfı, C# nesneleri ile JSON dizeleri arasında hızlı ve verimli bir dönüşüm sağlamak üzere tasarlanmıştır. Dahili C++ koduyla çalışması sayesinde, özellikle basit veri yapıları için oldukça performanslıdır. Ancak, bazı kısıtlamaları da vardır:

  • Sadece public alanları ve [SerializeField] niteliği ile işaretlenmiş private alanları serileştirir. Property'leri (özellikleri) serileştirmez.
  • Serileştirilecek sınıfın [Serializable] niteliği ile işaretlenmiş olması gerekir.
  • Dictionary, HashSet gibi bazı karmaşık koleksiyon tiplerini doğrudan desteklemez.
  • Özel serileştirme mantığı (custom converters) ekleme esnekliği sunmaz.

Bu kısıtlamalara rağmen, çoğu temel Unity JSON Dönüştürme ihtiyacı için JsonUtility mükemmel bir çözümdür.

JsonUtility.ToJson() Temelleri

JsonUtility.ToJson() metodu, bir C# nesnesini alır ve onu JSON formatında bir dizeye dönüştürür. Metodun temel imzası şöyledir:

public static string ToJson(object obj, bool prettyPrint = false);
  • obj: JSON'a dönüştürülecek C# nesnesi.
  • prettyPrint: Eğer true ise, JSON çıktısı okunabilirliği artırmak için girintili ve satır aralıklı olarak biçimlendirilir. Varsayılan olarak false'tur ve çıktıyı tek bir satırda sıkıştırır.

Şimdi basit bir örnekle nasıl çalıştığını görelim:

using UnityEngine;

[System.Serializable]
public class OyuncuVerisi
{
    public string oyuncuAdi;
    public int seviye;
    public float deneyimPuani;
    public bool aktifMi;
}

public class JsonOrnek : MonoBehaviour
{
    void Start()
    {
        OyuncuVerisi oyuncu = new OyuncuVerisi();
        oyuncu.oyuncuAdi = "Kahraman";
        oyuncu.seviye = 10;
        oyuncu.deneyimPuani = 543.21f;
        oyuncu.aktifMi = true;

        // OyuncuVerisi nesnesini JSON'a dönüştür
        string jsonString = JsonUtility.ToJson(oyuncu);
        Debug.Log("Sıkıştırılmış JSON: " + jsonString);

        // Okunabilir formatta JSON'a dönüştür
        string prettyJsonString = JsonUtility.ToJson(oyuncu, true);
        Debug.Log("Okunabilir JSON:\n" + prettyJsonString);
    }
}

Bu kodu çalıştırdığınızda konsolda aşağıdaki gibi bir çıktı göreceksiniz:

Sıkıştırılmış JSON: {"oyuncuAdi":"Kahraman","seviye":10,"deneyimPuani":543.21,"aktifMi":true}
Okunabilir JSON:
{
    "oyuncuAdi": "Kahraman",
    "seviye": 10,
    "deneyimPuani": 543.21,
    "aktifMi": true
}

Gördüğünüz gibi, prettyPrint parametresi JSON çıktısının biçimlendirmesini değiştirerek daha rahat okunmasını sağlıyor. Bu, özellikle hata ayıklama veya yapılandırma dosyalarını manuel olarak düzenlerken çok işinize yarayacaktır.

İç İçe Nesneleri Serileştirme

JsonUtility, iç içe geçmiş (nested) sınıfları da sorunsuz bir şekilde serileştirebilir. Tek yapmanız gereken, iç sınıfları da [System.Serializable] niteliği ile işaretlemektir.

using UnityEngine;

[System.Serializable]
public class EnvanterEsyasi
{
    public string esyaAdi;
    public int miktar;
}

[System.Serializable]
public class OyuncuProfili
{
    public string kullaniciAdi;
    public int id;
    public EnvanterEsyasi[] envanter;
}

public class JsonNestedOrnek : MonoBehaviour
{
    void Start()
    {
        OyuncuProfili profil = new OyuncuProfili();
        profil.kullaniciAdi = "GamerX";
        profil.id = 12345;
        profil.envanter = new EnvanterEsyasi[]
        {
            new EnvanterEsyasi { esyaAdi = "Kılıç", miktar = 1 },
            new EnvanterEsyasi { esyaAdi = "İksir", miktar = 5 }
        };

        string jsonProfil = JsonUtility.ToJson(profil, true);
        Debug.Log("Oyuncu Profili JSON:\n" + jsonProfil);
    }
}

Bu örnekte, OyuncuProfili sınıfı içinde EnvanterEsyasi tipinde bir dizi (array) bulunmaktadır. JsonUtility.ToJson(), bu yapıyı da doğru bir şekilde JSON'a dönüştürecektir.

Pratik İpuçları ve En İyi Uygulamalar

İpucu 1: Özel Alanları Serileştirme (`[SerializeField]`)

Varsayılan olarak, JsonUtility sadece public alanları serileştirir. Eğer private veya protected bir alanı serileştirmek isterseniz, bu alanın üzerine [SerializeField] niteliğini eklemeniz gerekir.

using UnityEngine;

[System.Serializable]
public class Ayarlar
{
    [SerializeField] private float sesSeviyesi = 0.8f; // private ama serileştirilecek
    public bool tamEkran = true;

    // Bu metot, serileştirme için kullanılmaz, sadece değeri göstermek için.
    public float GetSesSeviyesi() { return sesSeviyesi; }
}

public class AyarlarOrnek : MonoBehaviour
{
    void Start()
    {
        Ayarlar ayar = new Ayarlar();
        // ayar.sesSeviyesi = 0.5f; // private olduğu için doğrudan erişilemez
        string jsonAyarlar = JsonUtility.ToJson(ayar, true);
        Debug.Log("Ayarlar JSON:\n" + jsonAyarlar);
    }
}

Çıktıda sesSeviyesi'nin de JSON'da yer aldığını göreceksiniz. Bu, sınıfınızın iç tutarlılığını bozmadan veri serileştirmesi yapmanızı sağlar.

İpucu 2: Dizileri ve Listeleri Serileştirme (Wrapper Sınıfı)

JsonUtility, doğrudan bir C# dizisini veya List<T> nesnesini JSON'a dönüştürmede zorluk yaşar. Yani, JsonUtility.ToJson(myList) doğrudan çalışmaz. Bu durum için bir Unity JSON Dönüştürme hilesi olarak bir 'sarmalayıcı' (wrapper) sınıf kullanmanız gerekir.

using UnityEngine;
using System.Collections.Generic;

[System.Serializable]
public class Gorev
{
    public string baslik;
    public bool tamamlandi;
}

// Görev listesini sarmalayacak bir sınıf
[System.Serializable]
public class GorevListesiWrapper
{
    public List<Gorev> gorevler;

    public GorevListesiWrapper(List<Gorev> list)
    {
        gorevler = list;
    }
}

public class GorevOrnek : MonoBehaviour
{
    void Start()
    {
        List<Gorev> tumGorevler = new List<Gorev>()
        {
            new Gorev { baslik = "Oyun Başlat", tamamlandi = true },
            new Gorev { baslik = "Seviye 1'i Bitir", tamamlandi = false },
            new Gorev { baslik = "Yeni Karakter Yarat", tamamlandi = false }
        };

        // Wrapper sınıfını kullanarak serileştirme
        GorevListesiWrapper wrapper = new GorevListesiWrapper(tumGorevler);
        string jsonGorevler = JsonUtility.ToJson(wrapper, true);
        Debug.Log("Görevler JSON:\n" + jsonGorevler);
    }
}

Bu yöntemle, listeniz JSON içinde bir anahtar altında (bu örnekte `"gorevler"`) düzgün bir şekilde serileştirilir.

İpucu 3: JSON Verisini Dosyaya Kaydetme ve Yükleme

JSON'a dönüştürdüğünüz verileri genellikle bir dosyaya kaydetmek istersiniz. System.IO kütüphanesini kullanarak bu işlemi kolayca yapabilirsiniz.

using UnityEngine;
using System.IO;

[System.Serializable]
public class OyunDurumu
{
    public string sonKayitTarihi;
    public int mevcutBolum;
    public float oynamaSuresi;
}

public class KayitYukleOrnek : MonoBehaviour
{
    private string kayitDosyasiYolu;

    void Awake()
    {
        // Kayıt dosyasının yolu (platforma göre değişir, kalıcı bir konum)
        kayitDosyasiYolu = Path.Combine(Application.persistentDataPath, "oyun_durumu.json");
    }

    void Start()
    {
        KaydetOyunDurumu();
        YukleOyunDurumu();
    }

    void KaydetOyunDurumu()
    {
        OyunDurumu durum = new OyunDurumu();
        durum.sonKayitTarihi = System.DateTime.Now.ToString();
        durum.mevcutBolum = 5;
        durum.oynamaSuresi = 120.5f;

        string json = JsonUtility.ToJson(durum, true);

        File.WriteAllText(kayitDosyasiYolu, json);
        Debug.Log("Oyun durumu kaydedildi: " + kayitDosyasiYolu);
    }

    void YukleOyunDurumu()
    {
        if (File.Exists(kayitDosyasiYolu))
        {
            string json = File.ReadAllText(kayitDosyasiYolu);
            OyunDurumu yuklenenDurum = JsonUtility.FromJson<OyunDurumu>(json);
            Debug.Log($"Oyun durumu yüklendi: Bölüm {yuklenenDurum.mevcutBolum}, Son Kayıt: {yuklenenDurum.sonKayitTarihi}");
        }
        else
        {
            Debug.LogWarning("Kayıt dosyası bulunamadı.");
        }
    }
}

Application.persistentDataPath, cihazın kalıcı veri depolama alanını işaret eder ve bu yol, farklı platformlarda (Windows, Android, iOS) güvenli bir şekilde dosya yazıp okumanızı sağlar.

Yaygın Hatalar ve Çözümleri

1. `[System.Serializable]` Nitelik Eksikliği:

  • Hata: Serileştirmeye çalıştığınız sınıfın veya iç içe sınıfın [System.Serializable] niteliği eksik. JsonUtility bu sınıfları görmezden gelir.
  • Çözüm: Serileştirmek istediğiniz her sınıfın başına [System.Serializable] ekleyin.

2. Desteklenmeyen Tipler:

  • Hata: Dictionary<TKey, TValue>, HashSet<T> gibi kompleks koleksiyonları doğrudan serileştirmeye çalışmak.
  • Çözüm: Bu tipler için özel sarmalayıcı sınıflar oluşturmanız veya JSON'a dönüştürmeden önce bunları desteklenen tiplere (örn. List<KeyValuePair<TKey, TValue>>) dönüştürmeniz gerekir. Daha karmaşık senaryolar için üçüncü taraf JSON kütüphaneleri (örn. Newtonsoft.Json) düşünebilirsiniz, ancak bu Unity JSON Dönüştürme için ek bağımlılık ve performans maliyeti getirecektir.

3. Dizileri/Listeleri Doğrudan Serileştirme:

  • Hata: Doğrudan JsonUtility.ToJson(myList); çağırmak, istenen JSON çıktısını vermez.
  • Çözüm: Yukarıda gösterildiği gibi, liste veya dizinizi sarmalayacak [System.Serializable] nitelikli bir sınıf oluşturun ve bu sarmalayıcı sınıfı serileştirin.

4. Property'lerin (Özelliklerin) Serileştirilmemesi:

  • Hata: Sınıfınızdaki property'ler (public int MyProperty { get; set; } gibi) JSON çıktısında görünmez.
  • Çözüm: JsonUtility sadece alanları (fields) serileştirir. Eğer bir property'nin değerini serileştirmek istiyorsanız, bu değeri tutan bir field tanımlayın ve eğer private ise [SerializeField] ile işaretleyin.

Performans ve Optimizasyon Notları

JsonUtility, Unity'nin dahili C++ kodu üzerine inşa edildiği için oldukça hızlıdır. Özellikle basit ve orta karmaşıklıktaki veri yapılarını serileştirip serileştirmek için mükemmel bir seçimdir. Performans açısından, diğer popüler C# JSON kütüphanelerine (örn. Newtonsoft.Json) kıyasla genellikle daha az bellek kullanır ve daha hızlı çalışır, çünkü Unity'nin kendi serileştirme sistemiyle entegredir.

Ancak, uygulamanızın aşırı derecede büyük JSON dosyalarıyla veya çok sayıda karmaşık nesneyle sürekli işlem yapması gerekiyorsa, her zaman profilleyici (Profiler) kullanarak performans darboğazlarını kontrol etmelisiniz. Çoğu oyun senaryosunda, Unity JSON Dönüştürme için JsonUtility'nin performansı fazlasıyla yeterli olacaktır.

Sonuç

JsonUtility.ToJson() metodu, Unity'de veri serileştirme ihtiyaçlarınız için güçlü, hızlı ve kullanımı kolay bir araçtır. [System.Serializable] niteliğini doğru kullanmayı, diziler ve listeler için sarmalayıcı sınıflar oluşturmayı ve yaygın hatalardan kaçınmayı öğrenerek, oyunlarınızda ve uygulamalarınızda sağlam ve verimli bir veri yönetimi yapısı kurabilirsiniz. Bu rehberdeki bilgilerle, Unity JSON Dönüştürme işlemlerini sorunsuz bir şekilde gerçekleştirebileceksiniz.

🧠 Ders Sonu Değerlendirme Testi

Dersi tamamladıktan sonra bilgilerinizi test edin ve ekstra puanlar kazanın.

🔥 +50 XP Ödül
🔒

Sınava Katılmak İçin Giriş Yapın

Bu ders sonu testini çözebilmek, bilginizi test edip **+50 XP** kazanmak ve **Sınav Şampiyonu** rozetinin kilidini açmak için üye girişi yapmalısınız.

Yorumlar (0)

Yorum yazabilmek ve derslere katkıda bulunabilmek için giriş yapmalısınız.

İlk yorumu siz yapın!