{"id":34198,"date":"2025-11-12T17:01:32","date_gmt":"2025-11-12T14:01:32","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/"},"modified":"2025-11-12T17:01:32","modified_gmt":"2025-11-12T14:01:32","slug":"unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/","title":{"rendered":"Unity&#8217;de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler"},"content":{"rendered":"<p><body><\/p>\n<p>\n        Oyun geli\u015ftirme s\u00fcrecinde, oyuncular\u0131n ilerlemesini kaydetmek ve bir sonraki oturumda kald\u0131klar\u0131 yerden devam etmelerini sa\u011flamak kritik bir \u00f6neme sahiptir. Peki, bu verileri nas\u0131l daha d\u00fczenli, daha esnek ve daha performansl\u0131 bir \u015fekilde y\u00f6netebiliriz? Unity&#8217;de oyun verilerini kaydetmenin \u00e7e\u015fitli yollar\u0131 bulunmaktad\u0131r; \u00f6nceki yaz\u0131lar\u0131m\u0131zda PlayerPrefs ve JSON\/Binary serile\u015ftirmesi gibi y\u00f6ntemleri ele alm\u0131\u015ft\u0131k. Bu makalemizde ise, veri y\u00f6netimini tamamen yeni bir seviyeye ta\u015f\u0131yan, tasar\u0131m zaman\u0131 verilerini d\u00fczenlemede e\u015fsiz bir ara\u00e7 olan ScriptableObjects&#8217;\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Bu g\u00fc\u00e7l\u00fc Unity \u00f6zelli\u011fi ile oyun verilerinizi kal\u0131c\u0131 ve esnek bir \u015fekilde nas\u0131l saklayaca\u011f\u0131n\u0131z\u0131, tasar\u0131mda kolayl\u0131k ve performansta art\u0131\u015f i\u00e7in ad\u0131m ad\u0131m rehberimizi takip ederek \u00f6\u011frenin.\n    <\/p>\n<p>\n        Her oyunun temelinde bir veri y\u00f6netimi yatar. Oyuncu ilerlemesi, envanter, karakter istatistikleri, g\u00f6rev durumu ve hatta oyun i\u00e7i ayarlar gibi say\u0131s\u0131z bilgi, oyuncu deneyiminin ayr\u0131lmaz bir par\u00e7as\u0131d\u0131r. Bu verilerin g\u00fcvenli, tutarl\u0131 ve eri\u015filebilir bir \u015fekilde kaydedilmesi, bir oyunun ba\u015far\u0131s\u0131 i\u00e7in hayati \u00f6nem ta\u015f\u0131r. Aksi takdirde, oyuncular\u0131n emeklerinin bo\u015fa gitmesi, hayal k\u0131r\u0131kl\u0131\u011f\u0131na ve nihayetinde oyunu b\u0131rakmalar\u0131na yol a\u00e7abilir. PlayerPrefs gibi basit \u00e7\u00f6z\u00fcmler k\u00fc\u00e7\u00fck \u00f6l\u00e7ekli veriler i\u00e7in uygun olsa da, daha karma\u015f\u0131k yap\u0131daki oyunlar i\u00e7in yetersiz kal\u0131r. JSON veya Binary serile\u015ftirmesi, daha geni\u015f veri k\u00fcmelerini y\u00f6netme konusunda daha fazla esneklik sunar ancak \u00e7o\u011fu zaman verilerin \u00e7al\u0131\u015fma zaman\u0131nda (runtime) olu\u015fturulup kaydedilmesini gerektirir.\n    <\/p>\n<p>\n        \u0130\u015fte tam da bu noktada ScriptableObjects devreye giriyor ve oyun geli\u015ftiricilere veri y\u00f6netimi konusunda devrim niteli\u011finde bir yakla\u015f\u0131m sunuyor. ScriptableObjects, temel olarak disk \u00fczerinde bir &#8220;Asset&#8221; olarak var olan, MonoBehaviour&#8217;dan t\u00fcremeyen, ancak Unity Edit\u00f6r&#8217;\u00fcnde olu\u015fturulabilen ve y\u00f6netilebilen bir veri kapsay\u0131c\u0131s\u0131d\u0131r. Bu, onlar\u0131n \u00e7al\u0131\u015fma zaman\u0131 (runtime) bile\u015fenlerinden ba\u011f\u0131ms\u0131z oldu\u011fu anlam\u0131na gelir; yani bir Scene&#8217;e veya GameObject&#8217;e ba\u011fl\u0131 olmak zorunda de\u011fillerdir. Bu ba\u011f\u0131ms\u0131zl\u0131k, verilerin yeniden kullan\u0131labilirli\u011fini, d\u00fczenlenmesini ve farkl\u0131 oyun objeleri aras\u0131nda payla\u015f\u0131lmas\u0131n\u0131 inan\u0131lmaz derecede kolayla\u015ft\u0131r\u0131r. \u00d6rne\u011fin, bir d\u00fc\u015fman\u0131n temel istatistiklerini i\u00e7eren bir ScriptableObject olu\u015fturabilir ve bu ayn\u0131 ScriptableObject asset&#8217;ini onlarca farkl\u0131 d\u00fc\u015fman prefab&#8217;\u0131nda kullanabilirsiniz. Bu sayede, tek bir merkezi yerden t\u00fcm d\u00fc\u015fmanlar\u0131n belirli bir \u00f6zelli\u011fini g\u00fcncelleyebilir, hata yapma riskini azaltabilir ve geli\u015ftirme s\u00fcrecini h\u0131zland\u0131rabilirsiniz.\n    <\/p>\n<p>\n        Geleneksel yakla\u015f\u0131mlarda, veri \u00e7o\u011fu zaman do\u011frudan GameObject&#8217;ler \u00fczerindeki bile\u015fenlere g\u00f6m\u00fcl\u00fcr. Bu durum, verilerin tekrar\u0131n\u0131 art\u0131r\u0131r, d\u00fczenlemeyi zorla\u015ft\u0131r\u0131r ve projenin \u00f6l\u00e7eklenebilirli\u011fini s\u0131n\u0131rlar. ScriptableObjects ise, verileri mant\u0131ksal olarak ayr\u0131\u015ft\u0131rma ve merkezi bir konumda toplama imkan\u0131 sunar. Bu, \u00f6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k projelerde, oyunun veri mimarisini temiz, anla\u015f\u0131l\u0131r ve bak\u0131m\u0131 kolay hale getirir. Oyuncu profilleri, envanter \u00f6\u011feleri, yetenek a\u011fa\u00e7lar\u0131, d\u00fc\u015fman tipleri, seviye konfig\u00fcrasyonlar\u0131 gibi pek \u00e7ok farkl\u0131 veri t\u00fcr\u00fc ScriptableObjects arac\u0131l\u0131\u011f\u0131yla \u00e7ok daha etkili bir \u015fekilde y\u00f6netilebilir. Bu yakla\u015f\u0131m, sadece geli\u015ftirme verimlili\u011fini art\u0131rmakla kalmaz, ayn\u0131 zamanda oyunun performans\u0131na da olumlu katk\u0131da bulunur, \u00e7\u00fcnk\u00fc bellekte ayn\u0131 verinin birden \u00e7ok kopyas\u0131 yerine tek bir referans tutulur. Bu da, \u00f6zellikle mobil platformlar gibi bellek k\u0131s\u0131tl\u0131 ortamlarda fark yaratabilir.\n    <\/p>\n<h2>ScriptableObjects Nedir ve Veri Y\u00f6netimine Nas\u0131l Yeni Bir Bak\u0131\u015f A\u00e7ar?<\/h2>\n<p>\n        ScriptableObjects, Unity&#8217;nin en az anla\u015f\u0131lan ama en g\u00fc\u00e7l\u00fc \u00f6zelliklerinden biridir. Temel olarak, bunlar <code>UnityEngine.ScriptableObject<\/code> s\u0131n\u0131f\u0131ndan t\u00fcreyen ve proje i\u00e7erisinde bir varl\u0131k (Asset) olarak diskte kaydedilebilen C# s\u0131n\u0131flar\u0131d\u0131r. En belirgin farklar\u0131, <code>MonoBehaviour<\/code>&#8216;dan t\u00fcrememeleridir; yani bir sahneye bir bile\u015fen olarak eklenemezler ve bir GameObject&#8217;in ya\u015fam d\u00f6ng\u00fcs\u00fcne (Awake, Start, Update vb.) do\u011frudan kat\u0131lmazlar. Peki, bu onlar\u0131 veri y\u00f6netimi i\u00e7in neden bu kadar ideal k\u0131lar?\n    <\/p>\n<p>\n        Birincisi, <strong>ba\u011f\u0131ms\u0131zl\u0131k<\/strong>. ScriptableObjects, sahne veya GameObject hiyerar\u015fisinden tamamen ba\u011f\u0131ms\u0131zd\u0131r. Bu, onlar\u0131 oyununuzdaki farkl\u0131 nesneler aras\u0131nda veya hatta farkl\u0131 sahneler aras\u0131nda payla\u015f\u0131labilir veri kapsay\u0131c\u0131lar\u0131 haline getirir. \u00d6rne\u011fin, bir RPG oyununda t\u00fcm e\u015fyalar\u0131n temel \u00f6zelliklerini (ad\u0131, a\u00e7\u0131klamas\u0131, simgesi, de\u011feri) i\u00e7eren bir <code>ItemData<\/code> ScriptableObject&#8217;i tan\u0131mlayabilirsiniz. Her bir e\u015fya (k\u0131l\u0131\u00e7, z\u0131rh, iksir) bu <code>ItemData<\/code>&#8216;n\u0131n ayr\u0131 bir \u00f6rne\u011fi olacakt\u0131r, ancak t\u00fcm\u00fc ayn\u0131 yap\u0131ya sahip olacakt\u0131r. Bu yap\u0131, veri tekrar\u0131n\u0131 \u00f6nler ve tutarl\u0131l\u0131\u011f\u0131 sa\u011flar.\n    <\/p>\n<p>\n        \u0130kincisi, <strong>Edit\u00f6r Entegrasyonu<\/strong>. <code>[CreateAssetMenu]<\/code> niteli\u011fini kullanarak, Unity Edit\u00f6r&#8217;\u00fcnde sa\u011f t\u0131klayarak yeni bir ScriptableObject asset&#8217;i olu\u015fturabilirsiniz. Bu, oyun tasar\u0131mc\u0131lar\u0131n\u0131n veya seviye tasar\u0131mc\u0131lar\u0131n\u0131n do\u011frudan Edit\u00f6r \u00fczerinden veri girmelerini ve d\u00fczenlemelerini sa\u011flar, kod yazmaya gerek kalmadan oyunun i\u00e7eri\u011fini zenginle\u015ftirmelerine olanak tan\u0131r. Verilerin koddan ayr\u0131lmas\u0131, geli\u015ftirme s\u00fcre\u00e7lerini birbirinden ba\u011f\u0131ms\u0131z hale getirir ve paralel \u00e7al\u0131\u015fmay\u0131 kolayla\u015ft\u0131r\u0131r.\n    <\/p>\n<p>\n        \u00dc\u00e7\u00fcnc\u00fcs\u00fc, <strong>yeniden kullan\u0131labilirlik<\/strong>. Bir ScriptableObject asset&#8217;i bir kez olu\u015fturuldu\u011funda, projenin her yerinde referans olarak kullan\u0131labilir. Bu, ayn\u0131 d\u00fc\u015fman tipi i\u00e7in ayn\u0131 istatistikleri, ayn\u0131 mermi tipi i\u00e7in ayn\u0131 \u00f6zellikleri veya ayn\u0131 ses efekti ayarlar\u0131n\u0131 birden fazla yerde kullanmak istedi\u011finizde \u00e7ok de\u011ferlidir. Bellekte yaln\u0131zca tek bir ScriptableObject asset&#8217;inin bir kopyas\u0131 bulunur ve t\u00fcm referanslar bu tek kopyay\u0131 i\u015faret eder. Bu durum, bellek kullan\u0131m\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde optimize eder ve \u00e7al\u0131\u015fma zaman\u0131 performans\u0131n\u0131 art\u0131r\u0131r. Geleneksel C# s\u0131n\u0131flar\u0131, bir GameObject \u00fczerinde bir bile\u015fen olarak kullan\u0131ld\u0131\u011f\u0131nda veya bir de\u011fer tipi olarak kopyaland\u0131\u011f\u0131nda, her bir \u00f6rnek i\u00e7in bellek tahsisi gerektirir. ScriptableObjects ise referans tipi olarak \u00e7al\u0131\u015ft\u0131\u011f\u0131 ve bir Asset oldu\u011fu i\u00e7in bu t\u00fcr tekrar eden bellek tahsislerinden ka\u00e7\u0131nman\u0131z\u0131 sa\u011flar.\n    <\/p>\n<p>\n        Son olarak, <strong>verinin ayr\u0131\u015ft\u0131r\u0131lmas\u0131 ve mod\u00fclerlik<\/strong>. Oyun mant\u0131\u011f\u0131n\u0131 ve veriyi birbirinden ay\u0131rmak, daha temiz, daha s\u00fcrd\u00fcr\u00fclebilir ve daha esnek bir kod taban\u0131 olu\u015fturman\u0131n anahtar\u0131d\u0131r. ScriptableObjects bu ayr\u0131m\u0131 do\u011fal bir \u015fekilde destekler. Oyunun davran\u0131\u015fsal k\u0131sm\u0131 (\u00f6rne\u011fin, bir d\u00fc\u015fman\u0131n nas\u0131l hareket etti\u011fi veya sald\u0131rd\u0131\u011f\u0131) <code>MonoBehaviour<\/code>&#8216;lar taraf\u0131ndan y\u00f6netilirken, d\u00fc\u015fman\u0131n temel istatistikleri (can, hasar, h\u0131z\u0131) bir ScriptableObject taraf\u0131ndan sa\u011flanabilir. Bu mod\u00fcler yap\u0131, kodun okunabilirli\u011fini art\u0131r\u0131r, hata ay\u0131klamay\u0131 kolayla\u015ft\u0131r\u0131r ve gelecekteki de\u011fi\u015fiklikleri veya geni\u015fletmeleri basitle\u015ftirir. B\u00f6ylece, bir d\u00fc\u015fman davran\u0131\u015f\u0131n\u0131 de\u011fi\u015ftirmek istedi\u011finizde, veri yap\u0131s\u0131na dokunman\u0131za gerek kalmaz; ayn\u0131 \u015fekilde, d\u00fc\u015fman\u0131n istatistiklerini de\u011fi\u015ftirmek istedi\u011finizde, davran\u0131\u015f kodunu g\u00fcncellemek zorunda kalmazs\u0131n\u0131z. Bu g\u00fc\u00e7l\u00fc ayr\u0131m, b\u00fcy\u00fck \u00f6l\u00e7ekli oyun projelerinde geli\u015ftirme ekipleri aras\u0131ndaki i\u015fbirli\u011fini de \u00f6nemli \u00f6l\u00e7\u00fcde kolayla\u015ft\u0131r\u0131r.\n    <\/p>\n<h3>ScriptableObject Temel Kullan\u0131m\u0131: \u0130lk ScriptableObject&#8217;imizi Nas\u0131l Olu\u015ftururuz?<\/h3>\n<p>\n        \u015eimdi, ScriptableObjects&#8217;\u0131n temellerini pratik bir \u00f6rnekle peki\u015ftirelim. Bir oyuncu profili olu\u015fturmak ve bu profilin temel bilgilerini (oyuncu ad\u0131, seviye, deneyim puan\u0131) ScriptableObject kullanarak nas\u0131l saklayaca\u011f\u0131m\u0131z\u0131 g\u00f6relim.\n    <\/p>\n<p>\n        <strong>Ad\u0131m 1: ScriptableObject S\u0131n\u0131f\u0131n\u0131 Olu\u015fturma<\/strong><br \/>\n        \u00d6ncelikle, yeni bir C# beti\u011fi olu\u015fturun ve ad\u0131n\u0131 &#8220;PlayerProfileSO&#8221; koyun. \u0130\u00e7eri\u011fini a\u015fa\u011f\u0131daki gibi d\u00fczenleyin:\n    <\/p>\n<pre><code>\nusing UnityEngine;\n\n[CreateAssetMenu(fileName = \"YeniOyuncuProfili\", menuName = \"Oyun Verileri\/Oyuncu Profili\")]\npublic class PlayerProfileSO : ScriptableObject\n{\n    public string playerName = \"Yeni Oyuncu\";\n    public int level = 1;\n    public long experiencePoints = 0;\n    public int health = 100;\n    public int mana = 50;\n\n    public void GainExperience(int amount)\n    {\n        experiencePoints += amount;\n        Debug.Log($\"Oyuncu {playerName} {amount} deneyim kazand\u0131. Toplam: {experiencePoints}\");\n        CheckLevelUp();\n    }\n\n    private void CheckLevelUp()\n    {\n        \/\/ Basit bir seviye atlama mant\u0131\u011f\u0131\n        if (experiencePoints >= level * 100)\n        {\n            level++;\n            experiencePoints = 0; \/\/ Yeni seviyede deneyimi s\u0131f\u0131rla\n            Debug.Log($\"Oyuncu {playerName} seviye atlad\u0131! Yeni seviye: {level}\");\n        }\n    }\n\n    public void TakeDamage(int damageAmount)\n    {\n        health -= damageAmount;\n        Debug.Log($\"Oyuncu {playerName} {damageAmount} hasar ald\u0131. Kalan Can: {health}\");\n        if (health <= 0)\n        {\n            Debug.Log($\"{playerName} yenildi!\");\n        }\n    }\n\n    public void RestoreHealth(int amount)\n    {\n        health += amount;\n        if (health > 100) health = 100; \/\/ Maksimum can\u0131 a\u015fma\n        Debug.Log($\"{playerName} {amount} can yeniledi. G\u00fcncel Can: {health}\");\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\n        Buradaki kilit nokta <code>[CreateAssetMenu]<\/code> niteli\u011fidir. Bu nitelik sayesinde, Unity Edit\u00f6r'\u00fcnde proje penceresinde sa\u011f t\u0131klayarak \"Create\" -> \"Oyun Verileri\" -> \"Oyuncu Profili\" yoluyla bu ScriptableObject'ten bir asset olu\u015fturabilirsiniz. <code>fileName<\/code> varsay\u0131lan dosya ad\u0131n\u0131, <code>menuName<\/code> ise men\u00fcdeki hiyerar\u015fiyi belirler.\n    <\/p>\n<p>\n        <strong>Ad\u0131m 2: ScriptableObject Asset'ini Olu\u015fturma<\/strong><br \/>\n        Unity Edit\u00f6r'\u00fcne d\u00f6n\u00fcn. Proje pencerenizde, uygun bir klas\u00f6rde (\u00f6rne\u011fin \"Assets\/ScriptableObjects\") sa\u011f t\u0131klay\u0131n, \"Create\" -> \"Oyun Verileri\" -> \"Oyuncu Profili\" se\u00e7ene\u011fini t\u0131klay\u0131n. Yeni olu\u015fturulan asset'e \"MainPlayerProfile\" gibi bir ad verin. Inspector penceresinde, bu asset'in de\u011fi\u015fkenlerini (playerName, level, experiencePoints vb.) do\u011frudan d\u00fczenleyebilirsiniz.\n    <\/p>\n<p>\n        <strong>Ad\u0131m 3: ScriptableObject Verilerine Bir MonoBehaviour'dan Eri\u015fme<\/strong><br \/>\n        \u015eimdi, oyun i\u00e7inde bu oyuncu profili verilerine nas\u0131l eri\u015fece\u011fimizi g\u00f6relim. Yeni bir C# beti\u011fi olu\u015fturun, ad\u0131n\u0131 \"GameManager\" koyun ve bir GameObject'e ekleyin (\u00f6rne\u011fin bo\u015f bir GameObject olu\u015fturup ona ekleyin). \u0130\u00e7eri\u011fini a\u015fa\u011f\u0131daki gibi d\u00fczenleyin:\n    <\/p>\n<pre><code>\nusing UnityEngine;\n\npublic class GameManager : MonoBehaviour\n{\n    [SerializeField] private PlayerProfileSO currentPlayerProfile;\n\n    void Start()\n    {\n        if (currentPlayerProfile != null)\n        {\n            Debug.Log($\"Oyun Ba\u015flad\u0131! Oyuncu Ad\u0131: {currentPlayerProfile.playerName}, Seviye: {currentPlayerProfile.level}\");\n            \n            \/\/ Oyuncuya deneyim kazand\u0131ral\u0131m\n            currentPlayerProfile.GainExperience(50);\n            currentPlayerProfile.GainExperience(80);\n            currentPlayerProfile.TakeDamage(20);\n            currentPlayerProfile.RestoreHealth(10);\n        }\n        else\n        {\n            Debug.LogError(\"Oyuncu Profili ScriptableObject atanmad\u0131!\");\n        }\n    }\n\n    \/\/ Oyun durdu\u011funda profilin anl\u0131k durumunu kaydetmek i\u00e7in (runtime de\u011fi\u015fiklikleri asset'e kaydolmaz!)\n    \/\/ Bu k\u0131s\u0131m sonraki b\u00f6l\u00fcmde detayland\u0131r\u0131lacak.\n    void OnApplicationQuit()\n    {\n        if (currentPlayerProfile != null)\n        {\n            Debug.Log($\"Oyun Kapan\u0131yor. Son Seviye: {currentPlayerProfile.level}, Son Deneyim: {currentPlayerProfile.experiencePoints}\");\n            \/\/ Normalde burada bir kaydetme fonksiyonu \u00e7a\u011f\u0131r\u0131rd\u0131k\n        }\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\n        Unity Edit\u00f6r'\u00fcne geri d\u00f6n\u00fcn, GameManager bile\u015feninin Inspector penceresinde \"Current Player Profile\" alan\u0131n\u0131 g\u00f6receksiniz. Buraya, daha \u00f6nce olu\u015fturdu\u011funuz \"MainPlayerProfile\" asset'ini s\u00fcr\u00fckleyip b\u0131rak\u0131n. Oyunu \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131n\u0131zda, Debug.Log mesajlar\u0131n\u0131 konsolda g\u00f6receksiniz. PlayerProfileSO \u00fczerindeki metodlar\u0131 \u00e7a\u011f\u0131rarak verileri g\u00fcncelledi\u011finizi fark edeceksiniz. Ancak dikkat: Oyunu durdurdu\u011funuzda, Inspector penceresindeki \"MainPlayerProfile\" asset'inin verilerinin orijinal haline geri d\u00f6nd\u00fc\u011f\u00fcn\u00fc g\u00f6receksiniz (level 1, experience 0). Bunun nedeni, ScriptableObjects'\u0131n \u00e7al\u0131\u015fma zaman\u0131nda yap\u0131lan de\u011fi\u015fiklikleri otomatik olarak Asset dosyas\u0131na kaydetmemesidir. Bu, bir sonraki b\u00f6l\u00fcm\u00fcm\u00fcz\u00fcn ana konusudur: veri kal\u0131c\u0131l\u0131\u011f\u0131.\n    <\/p>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: ScriptableObjects sadece tekil veri setleri i\u00e7in de\u011fil, ayn\u0131 zamanda veri listeleri veya dizileri i\u00e7in de m\u00fckemmeldir. \u00d6rne\u011fin, bir <code>EnemyWaveDataSO<\/code> olu\u015fturup i\u00e7ine bir <code>List<EnemyProfileSO><\/code> tutarak farkl\u0131 d\u00fc\u015fman dalgalar\u0131n\u0131 tan\u0131mlayabilir ve bunlar\u0131 Edit\u00f6r \u00fczerinden kolayca ayarlayabilirsiniz.\n    <\/div>\n<h2>ScriptableObjects ile Veri Kal\u0131c\u0131l\u0131\u011f\u0131 Nas\u0131l Sa\u011flan\u0131r?<\/h2>\n<p>\n        \u00d6nceki b\u00f6l\u00fcmde de belirtildi\u011fi gibi, ScriptableObjects'a \u00e7al\u0131\u015fma zaman\u0131nda (runtime) yap\u0131lan de\u011fi\u015fiklikler, Unity Edit\u00f6r'\u00fc durduruldu\u011funda veya oyun kapat\u0131ld\u0131\u011f\u0131nda kaybolur. Bunun nedeni, ScriptableObjects'\u0131n temel olarak tasar\u0131m zaman\u0131 verilerini depolamak i\u00e7in tasarlanm\u0131\u015f olmalar\u0131d\u0131r; bir \"Asset\" olarak diskte saklan\u0131rlar ve \u00e7al\u0131\u015fma zaman\u0131ndaki de\u011fi\u015fiklikler ge\u00e7icidir. Bu durum, oyuncunun ilerlemesini veya oyunun dinamik durumunu kaydetmek istedi\u011fimizde bir zorluk te\u015fkil eder. Peki, bu sorunu nas\u0131l a\u015fabiliriz ve ScriptableObjects ile kal\u0131c\u0131 veri depolama yetene\u011fini nas\u0131l birle\u015ftirebiliriz?\n    <\/p>\n<p>\n        \u00c7\u00f6z\u00fcm, ScriptableObjects'\u0131 harici bir serile\u015ftirme mekanizmas\u0131yla birlikte kullanmakt\u0131r. Yani, oyun \u00e7al\u0131\u015f\u0131rken ScriptableObject'imizdeki verileri g\u00fcncelleyece\u011fiz, ancak oyunu kapatmadan \u00f6nce bu verilerin anl\u0131k durumunu harici bir dosyaya kaydedece\u011fiz (JSON, Binary veya ba\u015fka bir format kullanarak). Oyun ba\u015flad\u0131\u011f\u0131nda ise, bu harici dosyadan verileri okuyup ScriptableObject'imizin i\u00e7eri\u011fini g\u00fcncelleyece\u011fiz. Bu y\u00f6ntem, ScriptableObjects'\u0131n sa\u011flad\u0131\u011f\u0131 kolay veri y\u00f6netimi ve Edit\u00f6r entegrasyonu avantajlar\u0131ndan vazge\u00e7meden, ayn\u0131 zamanda veri kal\u0131c\u0131l\u0131\u011f\u0131 ihtiyac\u0131m\u0131z\u0131 da kar\u015f\u0131lamam\u0131z\u0131 sa\u011flar. Genellikle <code>JsonUtility<\/code>, basitli\u011fi ve platformlar aras\u0131 uyumlulu\u011fu nedeniyle bu t\u00fcr senaryolarda tercih edilen bir y\u00f6ntemdir.\n    <\/p>\n<h3>Vaka Analizi: Envanter Sistemi Veri Kayd\u0131<\/h3>\n<p>\n        Bir RPG oyununda oyuncunun envanterini d\u00fc\u015f\u00fcnelim. Her e\u015fya bir ScriptableObject (<code>InventoryItemSO<\/code>) olarak tan\u0131mlanabilir, ancak oyuncunun envanterindeki belirli bir e\u015fyan\u0131n say\u0131s\u0131 veya durumu \u00e7al\u0131\u015fma zaman\u0131nda de\u011fi\u015febilir. Bu dinamik verileri nas\u0131l kaydedip y\u00fckleyece\u011fiz?\n    <\/p>\n<p>\n        <strong>Ad\u0131m 1: Envanter \u00d6\u011fesi ScriptableObject'ini Tan\u0131mlama<\/strong><br \/>\n        \u00d6nce her bir envanter \u00f6\u011fesinin temel \u00f6zelliklerini tutacak bir ScriptableObject olu\u015ftural\u0131m:\n    <\/p>\n<pre><code>\nusing UnityEngine;\n\n[CreateAssetMenu(fileName = \"YeniEnvanterEsyasi\", menuName = \"Oyun Verileri\/Envanter Esyasi\")]\npublic class InventoryItemSO : ScriptableObject\n{\n    public string itemName = \"Yeni E\u015fya\";\n    public Sprite icon; \/\/ E\u015fya ikonu\n    [TextArea(3, 5)]\n    public string description = \"Bu bir e\u015fyad\u0131r.\";\n    public int value = 1; \/\/ E\u015fyan\u0131n de\u011feri\n    public bool isStackable = true; \/\/ \u0130stiflenebilir mi?\n    public int maxStackSize = 99; \/\/ Maksimum istif boyutu\n\n    \/\/ Benzersiz bir ID atamas\u0131 (iste\u011fe ba\u011fl\u0131 ama faydal\u0131)\n    public string itemID; \n\n    void OnEnable()\n    {\n        if (string.IsNullOrEmpty(itemID))\n        {\n            itemID = System.Guid.NewGuid().ToString(); \/\/ Otomatik benzersiz ID ata\n        }\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\n        Bu ScriptableObject'ten birka\u00e7 tane olu\u015fturun (\u00f6rne\u011fin \"Sword\", \"HealthPotion\").\n    <\/p>\n<p>\n        <strong>Ad\u0131m 2: Kaydedilebilir Veri Yap\u0131s\u0131 Olu\u015fturma<\/strong><br \/>\n        \u015eimdi, oyuncunun envanterindeki e\u015fyalar\u0131n anl\u0131k durumunu (hangi e\u015fya, ka\u00e7 tane) kaydedecek bir POCO (Plain Old C# Object) s\u0131n\u0131f\u0131 tan\u0131mlayal\u0131m. Bu s\u0131n\u0131f, <code>JsonUtility<\/code> taraf\u0131ndan serile\u015ftirilebilecek \u015fekilde tasarlanmal\u0131d\u0131r.\n    <\/p>\n<pre><code>\nusing System.Collections.Generic;\nusing UnityEngine; \/\/ Sadece Debug i\u00e7in\n\n[System.Serializable]\npublic class InventorySlotData\n{\n    public string itemID; \/\/ Hangi InventoryItemSO'ya ait oldu\u011funu belirten ID\n    public int quantity; \/\/ Bu e\u015fyadan ka\u00e7 tane var\n\n    public InventorySlotData(string id, int qty)\n    {\n        itemID = id;\n        quantity = qty;\n    }\n}\n\n[System.Serializable]\npublic class InventorySaveData\n{\n    public List<InventorySlotData> slots = new List<InventorySlotData>();\n\n    \/\/ Kolay eri\u015fim i\u00e7in (\u00f6rne\u011fin, t\u00fcm ScriptableObject'leri bir s\u00f6zl\u00fckte tutarak)\n    \/\/ Bu k\u0131s\u0131m genelde runtime'da doldurulur, serile\u015ftirilmez.\n    [System.NonSerialized] \n    public Dictionary<string, InventoryItemSO> itemDatabase; \n}\n<\/pre>\n<p><\/code><\/p>\n<p>\n        <strong>Ad\u0131m 3: Envanter Y\u00f6neticisi ve Kaydetme\/Y\u00fckleme Mant\u0131\u011f\u0131<\/strong><br \/>\n        Son olarak, bu verileri y\u00f6netecek ve kaydedip y\u00fckleyecek bir <code>InventoryManager<\/code> s\u0131n\u0131f\u0131 olu\u015ftural\u0131m. Bu s\u0131n\u0131f, <code>InventorySaveData<\/code> nesnesini kullanarak verileri diskten okuyacak ve diske yazacakt\u0131r.\n    <\/p>\n<pre><code>\nusing UnityEngine;\nusing System.IO;\nusing System.Collections.Generic;\nusing System.Linq; \/\/ LINQ i\u00e7in\n\npublic class InventoryManager : MonoBehaviour\n{\n    public List<InventoryItemSO> allAvailableItems; \/\/ Edit\u00f6rden atanacak t\u00fcm olas\u0131 e\u015fyalar\n    private InventorySaveData currentInventoryData;\n    private string savePath;\n\n    \/\/ \u00c7al\u0131\u015fma zaman\u0131nda envanterdeki e\u015fyalar\u0131n referanslar\u0131n\u0131 tutmak i\u00e7in\n    public Dictionary<string, int> playerInventory = new Dictionary<string, int>(); \/\/ itemID, quantity\n\n    void Awake()\n    {\n        savePath = Path.Combine(Application.persistentDataPath, \"inventory.json\");\n        currentInventoryData = new InventorySaveData();\n\n        \/\/ itemDatabase'i doldur (sadece bir kere yap\u0131l\u0131r)\n        currentInventoryData.itemDatabase = new Dictionary<string, InventoryItemSO>();\n        foreach (var item in allAvailableItems)\n        {\n            if (!string.IsNullOrEmpty(item.itemID))\n            {\n                currentInventoryData.itemDatabase[item.itemID] = item;\n            }\n        }\n\n        LoadInventory();\n    }\n\n    public void AddItem(InventoryItemSO item, int quantity)\n    {\n        if (item == null || string.IsNullOrEmpty(item.itemID))\n        {\n            Debug.LogError(\"Ge\u00e7ersiz e\u015fya veya e\u015fya ID'si!\");\n            return;\n        }\n\n        if (playerInventory.ContainsKey(item.itemID))\n        {\n            playerInventory[item.itemID] += quantity;\n        }\n        else\n        {\n            playerInventory.Add(item.itemID, quantity);\n        }\n        Debug.Log($\"{item.itemName} eklendi. Toplam: {playerInventory[item.itemID]}\");\n    }\n\n    public void RemoveItem(InventoryItemSO item, int quantity)\n    {\n        if (item == null || string.IsNullOrEmpty(item.itemID))\n        {\n            Debug.LogError(\"Ge\u00e7ersiz e\u015fya veya e\u015fya ID'si!\");\n            return;\n        }\n\n        if (playerInventory.ContainsKey(item.itemID))\n        {\n            playerInventory[item.itemID] -= quantity;\n            if (playerInventory[item.itemID] <= 0)\n            {\n                playerInventory.Remove(item.itemID);\n                Debug.Log($\"{item.itemName} envanterden kald\u0131r\u0131ld\u0131.\");\n            }\n            else\n            {\n                Debug.Log($\"{item.itemName} kald\u0131r\u0131ld\u0131. Kalan: {playerInventory[item.itemID]}\");\n            }\n        }\n    }\n\n    public void SaveInventory()\n    {\n        currentInventoryData.slots.Clear();\n        foreach (var entry in playerInventory)\n        {\n            currentInventoryData.slots.Add(new InventorySlotData(entry.Key, entry.Value));\n        }\n\n        string json = JsonUtility.ToJson(currentInventoryData, true); \/\/ true ile daha okunabilir format\n        File.WriteAllText(savePath, json);\n        Debug.Log(\"Envanter kaydedildi: \" + savePath);\n    }\n\n    public void LoadInventory()\n    {\n        if (File.Exists(savePath))\n        {\n            string json = File.ReadAllText(savePath);\n            InventorySaveData loadedData = JsonUtility.FromJson<InventorySaveData>(json);\n            \n            \/\/ Y\u00fcklenen verileri playerInventory'e aktar\n            playerInventory.Clear();\n            foreach (var slot in loadedData.slots)\n            {\n                playerInventory.Add(slot.itemID, slot.quantity);\n                \/\/ E\u011fer itemDatabase'imiz varsa, burada e\u015fya ScriptableObject'ine referans da alabiliriz\n                if (currentInventoryData.itemDatabase != null && currentInventoryData.itemDatabase.ContainsKey(slot.itemID))\n                {\n                    Debug.Log($\"Y\u00fcklendi: {currentInventoryData.itemDatabase[slot.itemID].itemName} x {slot.quantity}\");\n                }\n            }\n            Debug.Log(\"Envanter y\u00fcklendi.\");\n        }\n        else\n        {\n            Debug.Log(\"Kaydedilmi\u015f envanter bulunamad\u0131. Yeni envanter ba\u015flat\u0131l\u0131yor.\");\n            \/\/ \u0130lk kez oynayanlar i\u00e7in ba\u015flang\u0131\u00e7 e\u015fyalar\u0131 eklenebilir\n            \/\/ AddItem(allAvailableItems[0], 1); \/\/ \u00d6rne\u011fin ilk e\u015fyadan bir tane ekle\n        }\n    }\n\n    \/\/ Oyunu kapat\u0131rken envanteri kaydet\n    void OnApplicationQuit()\n    {\n        SaveInventory();\n    }\n\n    \/\/ Test i\u00e7in\n    void Update()\n    {\n        if (Input.GetKeyDown(KeyCode.K))\n        {\n            SaveInventory();\n        }\n        if (Input.GetKeyDown(KeyCode.L))\n        {\n            LoadInventory();\n        }\n        if (Input.GetKeyDown(KeyCode.A)) \/\/ E\u015fya ekle\n        {\n            if (allAvailableItems.Count > 0)\n            {\n                AddItem(allAvailableItems[Random.Range(0, allAvailableItems.Count)], 1);\n            }\n        }\n        if (Input.GetKeyDown(KeyCode.R)) \/\/ Rastgele e\u015fya \u00e7\u0131kar\n        {\n            if (playerInventory.Count > 0)\n            {\n                string randomItemID = playerInventory.Keys.ElementAt(Random.Range(0, playerInventory.Count));\n                RemoveItem(currentInventoryData.itemDatabase[randomItemID], 1);\n            }\n        }\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\n        Bu <code>InventoryManager<\/code> beti\u011fini bo\u015f bir GameObject'e ekleyin. Inspector'da \"All Available Items\" listesine daha \u00f6nce olu\u015fturdu\u011funuz <code>InventoryItemSO<\/code> asset'lerini s\u00fcr\u00fckleyip b\u0131rak\u0131n. Oyunu \u00e7al\u0131\u015ft\u0131r\u0131n, e\u015fya ekleyip \u00e7\u0131kar\u0131n (A ve R tu\u015flar\u0131yla). Sonra K tu\u015funa basarak kaydedin. Oyunu kapat\u0131p tekrar a\u00e7t\u0131\u011f\u0131n\u0131zda L tu\u015funa basman\u0131za gerek kalmadan <code>Awake()<\/code> i\u00e7inde otomatik olarak y\u00fcklenmeli ve envanterinizin kald\u0131\u011f\u0131 yerden devam etti\u011fini g\u00f6receksiniz. <code>OnApplicationQuit()<\/code> sayesinde, oyun normal bir \u015fekilde kapat\u0131ld\u0131\u011f\u0131nda envanteriniz otomatik olarak kaydedilecektir.\n    <\/p>\n<h2>Performans ve Bellek Y\u00f6netimi A\u00e7\u0131s\u0131ndan ScriptableObjects'\u0131n Avantajlar\u0131 Nelerdir?<\/h2>\n<p>\n        ScriptableObjects'\u0131n cazibesi sadece veri organizasyonu ve Edit\u00f6r entegrasyonuyla s\u0131n\u0131rl\u0131 de\u011fildir; ayn\u0131 zamanda oyunlar\u0131n\u0131z\u0131n performans\u0131n\u0131 ve bellek kullan\u0131m\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde optimize etme potansiyeline sahiptirler. Bu avantajlar, \u00f6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k oyunlarda veya mobil gibi bellek k\u0131s\u0131tl\u0131 platformlarda geli\u015ftirme yaparken hayati \u00f6neme sahip olabilir.\n    <\/p>\n<p>\n        <strong>1. Bellek Tekrar\u0131n\u0131n \u00d6nlenmesi:<\/strong> Geleneksel yakla\u015f\u0131mlarda, ayn\u0131 t\u00fcrdeki bir\u00e7ok GameObject'in benzer verileri kendi bile\u015fenlerinde saklamas\u0131 yayg\u0131nd\u0131r. \u00d6rne\u011fin, farkl\u0131 d\u00fc\u015fman GameObject'lerinin her biri kendi <code>EnemyStats<\/code> s\u0131n\u0131f\u0131n\u0131 tutabilir. Bu durumda, her bir d\u00fc\u015fman i\u00e7in ayr\u0131 bir <code>EnemyStats<\/code> nesnesi bellekte yer kaplar. E\u011fer oyununuzda y\u00fczlerce d\u00fc\u015fman varsa, bu durum \u00f6nemli bir bellek fazlal\u0131\u011f\u0131na yol a\u00e7abilir. ScriptableObjects bu sorunu ortadan kald\u0131r\u0131r. Bir <code>EnemyStatsSO<\/code> olu\u015fturur ve bu asset'i farkl\u0131 d\u00fc\u015fman prefab'lar\u0131 aras\u0131nda payla\u015f\u0131rs\u0131n\u0131z. Bellekte yaln\u0131zca bir <code>EnemyStatsSO<\/code> \u00f6rne\u011fi bulunur ve t\u00fcm d\u00fc\u015fmanlar bu tek \u00f6rne\u011fe referans verir. Bu, y\u00fczlerce veya binlerce d\u00fc\u015fman\u0131n\u0131z oldu\u011funda bellek kullan\u0131m\u0131nda dramatik bir d\u00fc\u015f\u00fc\u015f sa\u011flar.\n    <\/p>\n<p>\n        <strong>2. Daha Az Serile\u015ftirme Y\u00fck\u00fc:<\/strong> Sahne y\u00fckleme ve bo\u015faltma s\u0131ras\u0131nda veya kaydetme\/y\u00fckleme i\u015flemleri esnas\u0131nda verilerin serile\u015ftirilmesi ve deserializasyonu \u00f6nemli bir zaman alabilir. E\u011fer verileriniz ScriptableObjects i\u00e7inde merkezi olarak y\u00f6netiliyorsa, bu s\u00fcre\u00e7 daha verimli hale gelir. \u00d6zellikle oyununuzda \u00e7ok say\u0131da GameObject varsa ve bu objeler kendi i\u00e7lerinde b\u00fcy\u00fck veri yap\u0131lar\u0131n\u0131 bar\u0131nd\u0131r\u0131yorsa, her bir GameObject'in serile\u015ftirilmesi uzun s\u00fcrebilir. ScriptableObjects ile, tasar\u0131m zaman\u0131 verileri zaten asset olarak serile\u015ftirilmi\u015f durumdad\u0131r ve \u00e7al\u0131\u015fma zaman\u0131nda sadece referanslar y\u00fcklenir. Runtime'da kaydedilen dynamic veriler i\u00e7in ise, yukar\u0131da g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi sadece de\u011fi\u015fen ve kaydedilmesi gereken verileri i\u00e7eren minimal bir yap\u0131 serile\u015ftirilir, bu da i\u015flemi h\u0131zland\u0131r\u0131r.\n    <\/p>\n<p>\n        <strong>3. Editor Performans\u0131 ve \u0130\u015f Ak\u0131\u015f\u0131:<\/strong> Geli\u015ftirme s\u00fcrecinde, Unity Editor'\u00fc \u00fczerinde \u00e7al\u0131\u015f\u0131rken ScriptableObjects'\u0131n faydalar\u0131 daha da belirginle\u015fir. B\u00fcy\u00fck miktarda veriyi bir kerede toplu olarak d\u00fczenleyebilir, farkl\u0131 asset'ler aras\u0131nda kolayca s\u00fcr\u00fckle-b\u0131rak referanslar\u0131 olu\u015fturabilirsiniz. Bu, oyun i\u00e7eri\u011finin h\u0131zl\u0131 bir \u015fekilde olu\u015fturulmas\u0131na ve yinelemeli geli\u015ftirme d\u00f6ng\u00fclerinin h\u0131zlanmas\u0131na yard\u0131mc\u0131 olur. Verilerin koddan ayr\u0131 tutulmas\u0131, kod derlemeleri s\u0131ras\u0131nda de\u011fi\u015fiklik yapma ihtiyac\u0131n\u0131 azalt\u0131r ve b\u00f6ylece Editor'deki \"Compile\" bekleme s\u00fcrelerini k\u0131saltabilir.\n    <\/p>\n<p>\n        <strong>4. \u00d6nbellekleme ve \u00c7al\u0131\u015fma Zaman\u0131 Eri\u015fimi:<\/strong> ScriptableObjects, referans tipleri olduklar\u0131 i\u00e7in, bellekte tek bir kopyalar\u0131 bulunur ve bu kopyaya eri\u015fim \u00e7ok h\u0131zl\u0131d\u0131r. Bir GameObject \u00fczerinde her zaman bir de\u011fer tipini kopyalamak veya her ihtiya\u00e7 duyuldu\u011funda yeni bir nesne olu\u015fturmak yerine, \u00f6nceden y\u00fcklenmi\u015f bir ScriptableObject asset'ine do\u011frudan eri\u015febilirsiniz. Bu durum, \u00f6zellikle s\u0131k\u00e7a eri\u015filen ve payla\u015f\u0131lan veriler i\u00e7in mikro-optimizasyonlar sa\u011flayarak genel oyun performans\u0131na katk\u0131da bulunur. Karma\u015f\u0131k veri yap\u0131lar\u0131na sahip oyunlarda, veriye eri\u015fim s\u00fcrelerinin minimize edilmesi, ak\u0131c\u0131 bir oyun deneyimi i\u00e7in kritik \u00f6neme sahiptir.\n    <\/p>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: B\u00fcy\u00fck ve statik veri k\u00fcmeleri i\u00e7in (\u00f6rne\u011fin, bir d\u00fcnya haritas\u0131ndaki t\u00fcm konum noktalar\u0131, g\u00f6rev tan\u0131mlar\u0131) ScriptableObjects kullanmak, verilerin Edit\u00f6r'den kolayca d\u00fczenlenmesini ve oyun ba\u015flat\u0131ld\u0131\u011f\u0131nda h\u0131zl\u0131ca y\u00fcklenmesini sa\u011flar. Hatta bu ScriptableObjects'lar\u0131 bir \"Database\" ScriptableObject'i i\u00e7inde toplayarak merkezi bir eri\u015fim noktas\u0131 olu\u015fturabilirsiniz. Bu teknikle, ba\u015flang\u0131\u00e7 y\u00fckleme s\u00fcrelerini optimize edebilir ve bellek kullan\u0131m\u0131n\u0131 kontrol alt\u0131nda tutabilirsiniz.\n    <\/div>\n<h2>\u0130leri D\u00fczey Kullan\u0131m Senaryolar\u0131 ve En \u0130yi Uygulamalar<\/h2>\n<p>\n        ScriptableObjects'\u0131n temel ve veri kaydetme mekanizmalar\u0131n\u0131 \u00f6\u011frendikten sonra, \u015fimdi daha karma\u015f\u0131k senaryolarda nas\u0131l kullan\u0131labilece\u011fine ve en iyi uygulamalar\u0131na g\u00f6z atal\u0131m. Bu b\u00f6l\u00fcm, projelerinizde ScriptableObjects'\u0131 daha verimli ve g\u00fc\u00e7l\u00fc bir \u015fekilde entegre etmenize yard\u0131mc\u0131 olacakt\u0131r.\n    <\/p>\n<h3>Vaka Analizi: Karakter Yetenek A\u011fac\u0131 ve Geli\u015fimi<\/h3>\n<p>\n        Bir RPG oyununda karakterlerin yeteneklerini y\u00f6netmek genellikle karma\u015f\u0131k bir i\u015ftir. Her yetene\u011fin kendine \u00f6zg\u00fc \u00f6zellikleri, maliyetleri ve \u00f6n ko\u015fullar\u0131 olabilir. Ayr\u0131ca, oyuncunun hangi yetenekleri a\u00e7t\u0131\u011f\u0131n\u0131 da kaydetmemiz gerekir. ScriptableObjects bu senaryo i\u00e7in bi\u00e7ilmi\u015f kaftand\u0131r.\n    <\/p>\n<p>\n        <strong>1. Yetenek Tan\u0131mlamalar\u0131 \u0130\u00e7in SkillSO:<\/strong><br \/>\n        Her bir yetene\u011fi (\u00f6rne\u011fin \"Ate\u015f Topu\", \"H\u0131zl\u0131 Ko\u015fma\") bir <code>SkillSO<\/code> ScriptableObject'i olarak tan\u0131mlar\u0131z.\n    <\/p>\n<pre><code>\nusing UnityEngine;\nusing System.Collections.Generic;\n\n[CreateAssetMenu(fileName = \"YeniYetenek\", menuName = \"Oyun Verileri\/Yetenek\")]\npublic class SkillSO : ScriptableObject\n{\n    public string skillName = \"Yeni Yetenek\";\n    [TextArea(3, 5)]\n    public string description = \"Yetenek a\u00e7\u0131klamas\u0131.\";\n    public Sprite icon;\n    public int manaCost = 10;\n    public float cooldown = 5f;\n    public List<SkillSO> prerequisites; \/\/ Bu yetene\u011fi a\u00e7mak i\u00e7in gerekli yetenekler\n    public string skillID; \/\/ Benzersiz ID\n\n    void OnEnable()\n    {\n        if (string.IsNullOrEmpty(skillID))\n        {\n            skillID = System.Guid.NewGuid().ToString();\n        }\n    }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\n        <strong>2. Yetenek A\u011fac\u0131 Yap\u0131s\u0131 \u0130\u00e7in SkillTreeSO:<\/strong><br \/>\n        T\u00fcm yetenekleri ve bunlar\u0131n birbiriyle ili\u015fkilerini g\u00f6steren bir <code>SkillTreeSO<\/code> olu\u015fturabiliriz. Bu, genellikle sadece bir liste veya a\u011fa\u00e7 yap\u0131s\u0131 i\u00e7eren ve Edit\u00f6r \u00fczerinden kolayca g\u00f6rselle\u015ftirilebilen bir ScriptableObject olabilir.\n    <\/p>\n<pre><code>\nusing UnityEngine;\nusing System.Collections.Generic;\n\n[CreateAssetMenu(fileName = \"YeniYetenekAgaci\", menuName = \"Oyun Verileri\/Yetenek Agaci\")]\npublic class SkillTreeSO : ScriptableObject\n{\n    public List<SkillSO> allSkills; \/\/ Oyunun t\u00fcm yetenekleri\n    \/\/ \u0130stenirse, bu yeteneklerin birbiriyle olan ba\u011flant\u0131lar\u0131n\u0131 g\u00f6steren karma\u015f\u0131k bir yap\u0131 da eklenebilir.\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\n        <strong>3. Oyuncu \u0130lerlemesini Kaydetme:<\/strong><br \/>\n        Oyuncunun hangi yetenekleri a\u00e7t\u0131\u011f\u0131n\u0131 takip etmek i\u00e7in ayr\u0131 bir kaydetme s\u0131n\u0131f\u0131 (\u00f6rne\u011fin <code>PlayerSkillProgressData<\/code>) olu\u015ftururuz. Bu s\u0131n\u0131f, a\u00e7\u0131lan yeteneklerin ID'lerini bir <code>List<string><\/code> olarak tutar ve JSON ile serile\u015ftirilir.\n    <\/p>\n<pre><code>\nusing System.Collections.Generic;\n\n[System.Serializable]\npublic class PlayerSkillProgressData\n{\n    public List<string> unlockedSkillIDs = new List<string>();\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\n        <code>SkillManager<\/code> gibi bir MonoBehaviour, bu <code>PlayerSkillProgressData<\/code>'y\u0131 y\u00fckleyip kaydedecek ve <code>SkillTreeSO<\/code>'daki bilgilere g\u00f6re yetenekleri y\u00f6netecektir. Oyuncu bir yetenek a\u00e7t\u0131\u011f\u0131nda, o yetene\u011fin ID'sini <code>unlockedSkillIDs<\/code> listesine ekleriz ve oyunu kapatmadan \u00f6nce bu listeyi kaydederiz. Oyun ba\u015flad\u0131\u011f\u0131nda ise, listeyi y\u00fckleyip oyuncunun a\u00e7t\u0131\u011f\u0131 yetenekleri tekrar i\u015faretleriz.\n    <\/p>\n<h3>Runtime De\u011fi\u015fiklikleri Y\u00f6netme (Sadece Edit\u00f6rde)<\/h3>\n<p>\n        Yukar\u0131daki \u00f6rneklerde, ScriptableObjects'a runtime'da yapt\u0131\u011f\u0131m\u0131z de\u011fi\u015fikliklerin kal\u0131c\u0131 olmad\u0131\u011f\u0131n\u0131 g\u00f6rd\u00fck. Ancak bazen, \u00f6zellikle geli\u015ftirme ve hata ay\u0131klama s\u0131ras\u0131nda, ScriptableObject asset'lerinin de\u011ferlerini \u00e7al\u0131\u015fma zaman\u0131nda de\u011fi\u015ftirip bu de\u011fi\u015fiklikleri asset dosyas\u0131na kaydetmek isteyebiliriz. Bu, yaln\u0131zca Unity Edit\u00f6r'\u00fcnde m\u00fcmk\u00fcn olan bir durumdur ve <code>UnityEditor.EditorUtility.SetDirty(this)<\/code> ve <code>UnityEditor.AssetDatabase.SaveAssets()<\/code> gibi metodlar kullan\u0131larak yap\u0131l\u0131r. Bu metodlar <code>UnityEditor<\/code> namespace'inde oldu\u011fu i\u00e7in, build'de derlenmeyecek \u015fekilde <code>#if UNITY_EDITOR<\/code> makrolar\u0131 aras\u0131na al\u0131nmal\u0131d\u0131r.\n    <\/p>\n<pre><code>\n\/\/ PlayerProfileSO i\u00e7inde bir \u00f6rnek\npublic void SaveChangesToAsset()\n{\n#if UNITY_EDITOR\n    UnityEditor.EditorUtility.SetDirty(this); \/\/ Bu asset'in de\u011fi\u015fti\u011fini i\u015faretle\n    UnityEditor.AssetDatabase.SaveAssets(); \/\/ T\u00fcm kirli asset'leri kaydet\n    Debug.Log($\"{name} ScriptableObject asset'ine de\u011fi\u015fiklikler kaydedildi.\");\n#endif\n}\n<\/pre>\n<p><\/code><\/p>\n<p>\n        Bu fonksiyonu \u00e7a\u011f\u0131rd\u0131\u011f\u0131n\u0131zda, ScriptableObject'in g\u00fcncel durumu do\u011frudan asset dosyas\u0131na kaydedilir ve Editor'\u00fc kapat\u0131p a\u00e7san\u0131z bile de\u011fi\u015fiklikler korunur. Bu, \u00f6zellikle veri d\u00fczenleme ve test s\u00fcre\u00e7lerinde \u00e7ok faydal\u0131d\u0131r.\n    <\/p>\n<h3>Versiyonlama Stratejileri<\/h3>\n<p>\n        Oyununuz geli\u015ftik\u00e7e, ScriptableObject yap\u0131lar\u0131n\u0131z\u0131n da de\u011fi\u015fmesi ka\u00e7\u0131n\u0131lmazd\u0131r. Yeni alanlar eklenebilir, mevcutlar kald\u0131r\u0131labilir veya veri tipleri de\u011fi\u015febilir. Bu durumda, eski kaydedilmi\u015f verilerin yeni veri \u015femas\u0131yla uyumlu olmas\u0131n\u0131 sa\u011flamak \u00f6nemlidir.\n    <\/p>\n<ul>\n<li><strong>Basit Versiyonlama:<\/strong> Kaydedilen JSON dosyas\u0131na veya ScriptableObject'e bir <code>version<\/code> alan\u0131 ekleyin. Veri y\u00fcklenirken bu <code>version<\/code> numaras\u0131n\u0131 kontrol edin. E\u011fer eski bir versiyon ise, verileri yeni \u015femaya d\u00f6n\u00fc\u015ft\u00fcrecek \u00f6zel bir ge\u00e7i\u015f (migration) mant\u0131\u011f\u0131 uygulay\u0131n.<\/li>\n<li><strong>Geriye Uyumluluk:<\/strong> Yeni alanlar eklerken, bunlar\u0131 <code>[SerializeField]<\/code> ile i\u015faretleyin ve varsay\u0131lan de\u011ferler atay\u0131n. Eski veriler y\u00fcklenirken bu alanlar varsay\u0131lan de\u011ferlerini alacak ve hata olu\u015fmayacakt\u0131r.<\/li>\n<li><strong>A\u015f\u0131r\u0131 Karma\u015f\u0131k Durumlarda:<\/strong> E\u011fer veri \u015feman\u0131z s\u0131k s\u0131k ve radikal bir \u015fekilde de\u011fi\u015fiyorsa, daha geli\u015fmi\u015f serile\u015ftirme k\u00fct\u00fcphaneleri (\u00f6rne\u011fin Odin Inspector veya kendi custom serile\u015ftiricileriniz) veya harici bir veritaban\u0131 \u00e7\u00f6z\u00fcm\u00fc (SQLite) d\u00fc\u015f\u00fcnmek gerekebilir.<\/li>\n<\/ul>\n<p>\n        <strong>Mobil Uyumlu HTML ve Oyun Aray\u00fczleri:<\/strong> Makalenin mobil uyumluluk konusuna de\u011finmek gerekirse, web taraf\u0131nda oldu\u011fu gibi oyun aray\u00fczlerinde de responsive tasar\u0131m ilkeleri uygulanabilir. ScriptableObjects do\u011frudan HTML \u00fcretmez, ancak oyun i\u00e7i kullan\u0131c\u0131 aray\u00fczlerini (UI) tasarlarken, farkl\u0131 ekran boyutlar\u0131 ve \u00e7\u00f6z\u00fcn\u00fcrl\u00fckler i\u00e7in esnek UI panelleri ve d\u00fczenleri olu\u015fturmak m\u00fcmk\u00fcnd\u00fcr. Unity'nin UI sistemi (Canvas, Rect Transform, Layout Groups), web'deki media query'lere benzer \u015fekilde, ekran boyutuna g\u00f6re \u00f6\u011felerin konumunu, boyutunu ve hatta g\u00f6r\u00fcn\u00fcrl\u00fc\u011f\u00fcn\u00fc ayarlayabilen ara\u00e7lar sunar. \u00d6rne\u011fin, bir envanter ekran\u0131n\u0131n mobil cihazlarda daha kompakt, masa\u00fcst\u00fcnde ise daha geni\u015f bir g\u00f6r\u00fcn\u00fcm sunmas\u0131 i\u00e7in Canvas Scaler ve Layout Groups ile dinamik ayarlamalar yapabilirsiniz. Bu, ScriptableObjects ile y\u00f6netti\u011finiz verilerin (\u00f6rne\u011fin envanterdeki e\u015fyalar\u0131n listesi) her platformda en iyi \u015fekilde sunulmas\u0131n\u0131 sa\u011flar.\n    <\/p>\n<h2>ScriptableObjects Kullan\u0131rken Kar\u015f\u0131la\u015f\u0131labilecek Zorluklar ve \u00c7\u00f6z\u00fcmleri<\/h2>\n<p>\n        Her g\u00fc\u00e7l\u00fc ara\u00e7 gibi, ScriptableObjects'\u0131n da kendi zorluklar\u0131 ve dikkate al\u0131nmas\u0131 gereken noktalar\u0131 vard\u0131r. Bu b\u00f6l\u00fcmde, ScriptableObjects kullan\u0131rken kar\u015f\u0131la\u015fabilece\u011finiz yayg\u0131n sorunlar\u0131 ve bunlara y\u00f6nelik \u00e7\u00f6z\u00fcmleri ele alaca\u011f\u0131z, b\u00f6ylece projelerinizde sorunsuz bir \u015fekilde ilerleyebilirsiniz.\n    <\/p>\n<p>\n        <strong>1. Runtime De\u011fi\u015fikliklerinin Kal\u0131c\u0131 Olmamas\u0131 (En B\u00fcy\u00fck Zorluk):<\/strong><br \/>\n        *   <strong>Zorluk:<\/strong> Daha \u00f6nce de belirtti\u011fimiz gibi, oyun \u00e7al\u0131\u015f\u0131rken bir ScriptableObject'in de\u011ferlerini de\u011fi\u015ftirdi\u011finizde, bu de\u011fi\u015fiklikler Unity Edit\u00f6r'\u00fc durduruldu\u011funda veya oyun kapat\u0131ld\u0131\u011f\u0131nda asset dosyas\u0131na kaydedilmez ve kaybolur. Bu, \u00f6zellikle ba\u015flang\u0131\u00e7ta yan\u0131lt\u0131c\u0131 olabilir ve oyuncu verilerini kaydetmek i\u00e7in ek bir mekanizma gerektirir.<br \/>\n        *   <strong>\u00c7\u00f6z\u00fcm:<\/strong> Oyuncu verileri gibi dinamik verileri ScriptableObjects'a kaydetmek istiyorsan\u0131z, yukar\u0131daki \"Veri Kal\u0131c\u0131l\u0131\u011f\u0131\" b\u00f6l\u00fcm\u00fcnde a\u00e7\u0131kland\u0131\u011f\u0131 gibi harici bir serile\u015ftirme y\u00f6ntemi (JSON, Binary) kullanmal\u0131s\u0131n\u0131z. \u00c7al\u0131\u015fma zaman\u0131nda ScriptableObject'teki verileri g\u00fcncelleyin, ancak oyun kapat\u0131lmadan \u00f6nce bu verileri bir POCO s\u0131n\u0131f\u0131na aktar\u0131p diskteki bir dosyaya kaydedin. Oyun ba\u015flad\u0131\u011f\u0131nda, diskteki dosyadan verileri okuyup ScriptableObject'inizin ilgili alanlar\u0131n\u0131 g\u00fcncelleyin. Yaln\u0131zca Editor'de geli\u015ftirme yaparken kal\u0131c\u0131 de\u011fi\u015fikliklere ihtiyac\u0131n\u0131z varsa, <code>EditorUtility.SetDirty()<\/code> ve <code>AssetDatabase.SaveAssets()<\/code> kullanabilirsiniz, ancak bu kodlar\u0131 build'e dahil etmedi\u011finizden emin olun (<code>#if UNITY_EDITOR<\/code>).\n    <\/p>\n<p>\n        <strong>2. ScriptableObject Referanslar\u0131n\u0131n Kayb\u0131:<\/strong><br \/>\n        *   <strong>Zorluk:<\/strong> E\u011fer bir GameObject veya ba\u015fka bir ScriptableObject, bir ScriptableObject asset'ine referans veriyorsa ve siz bu asset'i proje penceresinde siler veya yerini de\u011fi\u015ftirirseniz, referans bozulabilir. Unity Edit\u00f6r'\u00fc genellikle bu referanslar\u0131 otomatik olarak g\u00fcncelleyebilse de, baz\u0131 durumlarda (\u00f6zellikle do\u011frudan koddan AssetDatabase ile manuel i\u015flem yap\u0131ld\u0131\u011f\u0131nda) sorunlar ya\u015fanabilir.<br \/>\n        *   <strong>\u00c7\u00f6z\u00fcm:<\/strong> ScriptableObject asset'lerinizi proje i\u00e7inde d\u00fczenli bir klas\u00f6r yap\u0131s\u0131nda tutun ve m\u00fcmk\u00fcn oldu\u011funca yerlerini de\u011fi\u015ftirmekten ka\u00e7\u0131n\u0131n. E\u011fer bir asset'i ta\u015f\u0131mak zorundaysan\u0131z, bunu Unity Edit\u00f6r'\u00fcn\u00fcn proje penceresinden s\u00fcr\u00fckleyip b\u0131rakarak yap\u0131n; b\u00f6ylece Unity referanslar\u0131 otomatik olarak g\u00fcncelleyebilir. Asset'leri silmeden \u00f6nce, \"Find References In Scene\" veya Inspector'daki sa\u011f t\u0131klama men\u00fcs\u00fcn\u00fc kullanarak hangi di\u011fer asset'lerin veya GameObject'lerin bu ScriptableObject'e referans verdi\u011fini kontrol edin.\n    <\/p>\n<p>\n        <strong>3. B\u00fcy\u00fck Veri K\u00fcmelerinin Y\u00f6netimi:<\/strong><br \/>\n        *   <strong>Zorluk:<\/strong> ScriptableObjects, harika bir veri y\u00f6netim arac\u0131 olsa da, gigabaytlarca veri i\u00e7eren devasa veri k\u00fcmeleri i\u00e7in en uygun \u00e7\u00f6z\u00fcm olmayabilir. \u00d6rne\u011fin, a\u00e7\u0131k d\u00fcnya haritas\u0131ndaki her bir a\u011fac\u0131n konumunu veya her NPC'nin bireysel diyalog sat\u0131rlar\u0131n\u0131 binlerce ayr\u0131 ScriptableObject olarak tutmak, Edit\u00f6r'de yava\u015flamalara veya disk boyutunda \u015fi\u015fkinli\u011fe yol a\u00e7abilir.<br \/>\n        *   <strong>\u00c7\u00f6z\u00fcm:<\/strong> B\u00fcy\u00fck veri k\u00fcmeleri i\u00e7in ScriptableObjects'\u0131 soyutlaman\u0131n bir yolu olarak kullan\u0131n, ancak ayr\u0131nt\u0131l\u0131 verileri harici dosyalarda (CSV, JSON, XML) veya hafif bir veritaban\u0131nda (SQLite) saklay\u0131n. ScriptableObject, bu harici veri kaynaklar\u0131na referanslar\u0131 veya y\u00fckleme mant\u0131\u011f\u0131n\u0131 tutabilir. \u00d6rne\u011fin, bir <code>WorldBiomeSO<\/code> sadece bir biyomun genel \u00f6zelliklerini tutarken, bu biyomdaki her a\u011fac\u0131n konumu ayr\u0131 bir CSV dosyas\u0131nda saklanabilir ve <code>WorldBiomeSO<\/code> bu dosyay\u0131 y\u00fcklemekten sorumlu olabilir. Bu yakla\u015f\u0131m, ScriptableObjects'\u0131n kolay y\u00f6netim avantajlar\u0131ndan faydalan\u0131rken, b\u00fcy\u00fck veri performans sorunlar\u0131n\u0131 da \u00e7\u00f6zmenize yard\u0131mc\u0131 olur.\n    <\/p>\n<p>\n        <strong>4. \u00c7ok Oyunculu Ortamlarda Senkronizasyon:<\/strong><br \/>\n        *   <strong>Zorluk:<\/strong> ScriptableObjects genellikle client-side veri y\u00f6netimi ve tek oyunculu oyunlar i\u00e7in harikad\u0131r. Ancak, \u00e7ok oyunculu bir oyunda ScriptableObjects'taki runtime de\u011fi\u015fikliklerini t\u00fcm istemciler veya sunucu aras\u0131nda senkronize etmek karma\u015f\u0131k bir s\u00fcre\u00e7tir. ScriptableObjects network \u00fczerinden otomatik olarak senkronize edilmez.<br \/>\n        *   <strong>\u00c7\u00f6z\u00fcm:<\/strong> \u00c7ok oyunculu ortamlarda, ScriptableObjects'\u0131 genellikle \"Salt Okunur\" veri tan\u0131mlamalar\u0131 i\u00e7in kullan\u0131n (\u00f6rne\u011fin e\u015fya \u00f6zellikleri, yetenek tan\u0131mlamalar\u0131). Oyuncunun envanteri, karakter istatistikleri gibi dinamik ve senkronize edilmesi gereken veriler i\u00e7in, oyununuzun a\u011f katman\u0131na entegre edilmi\u015f \u00f6zel veri yap\u0131lar\u0131 ve senkronizasyon mekanizmalar\u0131 kullan\u0131n (\u00f6rne\u011fin, Mirror'da SyncVars, Photon'da Custom Properties). ScriptableObjects, bu a\u011f veri yap\u0131lar\u0131n\u0131n kulland\u0131\u011f\u0131 temel tan\u0131mlamalar\u0131 sa\u011flamaya devam edebilir, ancak actual state'i a\u011f katman\u0131 y\u00f6netecek.\n    <\/p>\n<p>\n        Bu zorluklar\u0131 ve \u00e7\u00f6z\u00fcmleri bilmek, ScriptableObjects'\u0131 projelerinizde daha bilin\u00e7li ve etkili bir \u015fekilde kullanman\u0131z\u0131 sa\u011flayacakt\u0131r. Do\u011fru senaryolarda do\u011fru ara\u00e7lar\u0131 kullanmak, her zaman ba\u015far\u0131l\u0131 bir oyun geli\u015ftirme s\u00fcrecinin anahtar\u0131d\u0131r.\n    <\/p>\n<h2>Sonu\u00e7: ScriptableObjects ile Veri Y\u00f6netiminde Yeni Bir D\u00f6nem<\/h2>\n<p>\n        Unity'de oyun verilerini kaydetme ve y\u00f6netme serimizin \u00fc\u00e7\u00fcnc\u00fc b\u00f6l\u00fcm\u00fc olan bu makalede, ScriptableObjects'\u0131n g\u00fcc\u00fcn\u00fc ve esnekli\u011fini detayl\u0131 bir \u015fekilde inceledik. PlayerPrefs'in basitli\u011finden ve JSON\/Binary serile\u015ftirmesinin esnekli\u011finden sonra, ScriptableObjects'\u0131n veri y\u00f6netimini tamamen farkl\u0131 bir boyuta ta\u015f\u0131d\u0131\u011f\u0131n\u0131 g\u00f6rd\u00fck. Bu \u00f6zel asset t\u00fcrleri, verileri MonoBehaviour'lardan ay\u0131rarak, projenizde daha mod\u00fcler, yeniden kullan\u0131labilir ve s\u00fcrd\u00fcr\u00fclebilir bir yap\u0131 olu\u015fturman\u0131n kap\u0131lar\u0131n\u0131 aral\u0131yor.\n    <\/p>\n<p>\n        ScriptableObjects sayesinde, oyun tasar\u0131mc\u0131lar\u0131 ve geli\u015ftiriciler, kod taban\u0131ndan ba\u011f\u0131ms\u0131z olarak oyun i\u00e7eri\u011fini daha kolay bir \u015fekilde olu\u015fturabilir ve d\u00fczenleyebilirler. Performans a\u00e7\u0131s\u0131ndan, bellek tekrar\u0131n\u0131 \u00f6nlemesi ve veriye daha h\u0131zl\u0131 eri\u015fim sa\u011flamas\u0131, \u00f6zellikle b\u00fcy\u00fck \u00f6l\u00e7ekli ve bellek k\u0131s\u0131tl\u0131 projelerde \u00f6nemli avantajlar sunar. Envanter sistemleri, yetenek a\u011fa\u00e7lar\u0131, d\u00fc\u015fman tan\u0131mlamalar\u0131 ve seviye konfig\u00fcrasyonlar\u0131 gibi bir\u00e7ok karma\u015f\u0131k oyun sistemi i\u00e7in ScriptableObjects, veri mimarisi tasar\u0131m\u0131nda vazge\u00e7ilmez bir ara\u00e7 haline gelmi\u015ftir.\n    <\/p>\n<p>\n        Unutmamak gerekir ki, ScriptableObjects \u00e7al\u0131\u015fma zaman\u0131 de\u011fi\u015fikliklerini otomatik olarak kaydetmez. Bu nedenle, oyuncu ilerlemesi gibi dinamik veriler i\u00e7in harici bir serile\u015ftirme mekanizmas\u0131 (genellikle JSON) ile birle\u015ftirilmeleri gerekir. Ancak bu kombinasyon, hem tasar\u0131m zaman\u0131 verilerinin kolay y\u00f6netimini hem de \u00e7al\u0131\u015fma zaman\u0131 verilerinin kal\u0131c\u0131l\u0131\u011f\u0131n\u0131 bir araya getiren g\u00fc\u00e7l\u00fc bir hibrit \u00e7\u00f6z\u00fcm sunar. Art\u0131k bu bilgilere sahip oldu\u011funuza g\u00f6re, kendi projelerinizde ScriptableObjects'\u0131 denemekten \u00e7ekinmeyin. Oyunlar\u0131n\u0131z\u0131n veri y\u00f6netimini optimize edin ve geli\u015ftirme s\u00fcrecinizi bir \u00fcst seviyeye ta\u015f\u0131y\u0131n!\n    <\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<ul>\n<li>\n            <strong>S: ScriptableObject'ler sadece Edit\u00f6rde mi kullan\u0131l\u0131r, yoksa build'de de \u00e7al\u0131\u015f\u0131r m\u0131?<\/strong><br \/>\n            <strong>C:<\/strong> ScriptableObject'ler hem Unity Edit\u00f6r'\u00fcnde hem de oyunun build edilmi\u015f halinde (runtime) \u00e7al\u0131\u015f\u0131r. Asset olarak proje dosyalar\u0131n\u0131z\u0131n bir par\u00e7as\u0131 olurlar ve oyun \u00e7al\u0131\u015f\u0131rken belle\u011fe y\u00fcklenerek i\u00e7erdikleri verilere eri\u015filebilir. Ancak, runtime'da yap\u0131lan de\u011fi\u015fiklikler build'de de asset dosyas\u0131na kal\u0131c\u0131 olarak kaydedilmez; bunun i\u00e7in harici bir serile\u015ftirme mekanizmas\u0131 gerekir.\n        <\/li>\n<li>\n            <strong>S: ScriptableObject'leri ne zaman kullanmal\u0131y\u0131m, ne zaman normal C# s\u0131n\u0131flar\u0131n\u0131 tercih etmeliyim?<\/strong><br \/>\n            <strong>C:<\/strong> ScriptableObject'leri, verilerinizi GameObjects veya Scene'lerden ba\u011f\u0131ms\u0131z olarak merkezi bir yerde tan\u0131mlamak, Edit\u00f6r \u00fczerinden d\u00fczenlemek ve farkl\u0131 bile\u015fenler veya asset'ler aras\u0131nda kolayca payla\u015fmak istedi\u011finizde kullanmal\u0131s\u0131n\u0131z. \u00d6zellikle oyun varl\u0131klar\u0131n\u0131n (e\u015fya tan\u0131mlar\u0131, yetenekler, d\u00fc\u015fman tipleri) statik \u00f6zelliklerini tutmak i\u00e7in idealdirler. Normal C# s\u0131n\u0131flar\u0131n\u0131 ise, genellikle anl\u0131k, ge\u00e7ici verileri (hesaplamalar, sadece bir method i\u00e7inde kullan\u0131lan k\u00fc\u00e7\u00fck veri yap\u0131lar\u0131) veya <code>MonoBehaviour<\/code>'lar \u00fczerinde karma\u015f\u0131k bir davran\u0131\u015f\u0131n par\u00e7as\u0131 olarak kullanmak istedi\u011finizde tercih edebilirsiniz. E\u011fer veri s\u00fcrekli de\u011fi\u015fecek ve oyun durumuyla do\u011frudan ili\u015fkiliyse (\u00f6rne\u011fin bir sava\u015ftaki d\u00fc\u015fman\u0131n anl\u0131k can de\u011feri), genellikle <code>MonoBehaviour<\/code> i\u00e7indeki bir C# s\u0131n\u0131f\u0131 daha uygun olabilir.\n        <\/li>\n<li>\n            <strong>S: ScriptableObject'leri kaydederken g\u00fcvenlik endi\u015feleri var m\u0131? Oyuncular verileri de\u011fi\u015ftirebilir mi?<\/strong><br \/>\n            <strong>C:<\/strong> ScriptableObject'ler build edilmi\u015f oyunda asset olarak bulundu\u011fu i\u00e7in, e\u011fer harici bir serile\u015ftirme kullan\u0131p bu serile\u015ftirilmi\u015f dosyay\u0131 (\u00f6rne\u011fin JSON) \u015fifrelemezseniz, bilgili oyuncular oyun dosyalar\u0131n\u0131 inceleyerek bu verileri potansiyel olarak de\u011fi\u015ftirebilir. Temel ScriptableObject asset'lerinin kendisi do\u011frudan de\u011fi\u015ftirilemez (\u00e7\u00fcnk\u00fc oyun \u00e7al\u0131\u015f\u0131rken bunlar Asset paketinin bir par\u00e7as\u0131d\u0131r), ancak e\u011fer runtime'da kaydedilen harici bir dosyay\u0131 kullan\u0131yorsan\u0131z, o dosyan\u0131n i\u00e7eri\u011fi manip\u00fcle edilebilir. Ciddi g\u00fcvenlik gerektiren (\u00f6rne\u011fin \u00e7ok oyunculu oyunlarda hile \u00f6nleme) veriler i\u00e7in, verileri \u015fifrelemek, karma de\u011feri (hash) kontrol\u00fc yapmak veya g\u00fcvenilir sunucu taraf\u0131nda do\u011frulamak gibi ek \u00f6nlemler alman\u0131z gerekebilir.\n        <\/li>\n<li>\n            <strong>S: Bir ScriptableObject i\u00e7inde ba\u015fka bir ScriptableObject'e referans verebilir miyim?<\/strong><br \/>\n            <strong>C:<\/strong> Evet, kesinlikle! Bu, ScriptableObjects'\u0131n en g\u00fc\u00e7l\u00fc \u00f6zelliklerinden biridir ve karma\u015f\u0131k veri yap\u0131lar\u0131 olu\u015fturman\u0131n temelini olu\u015fturur. \u00d6rne\u011fin, bir <code>CharacterClassSO<\/code> (karakter s\u0131n\u0131f\u0131) i\u00e7inde, o s\u0131n\u0131fa \u00f6zel yetenekleri tan\u0131mlayan bir <code>List<SkillSO><\/code> tutabilirsiniz. Bu, veriler aras\u0131nda ili\u015fkiler kurman\u0131za ve Edit\u00f6r \u00fczerinden birbiriyle ba\u011flant\u0131l\u0131 veri asset'leri a\u011fac\u0131 olu\u015fturman\u0131za olanak tan\u0131r.\n        <\/li>\n<li>\n            <strong>S: Unity'nin kaydetme sistemiyle (Serialization System) ScriptableObjects'\u0131n ili\u015fkisi nedir?<\/strong><br \/>\n            <strong>C:<\/strong> ScriptableObjects, Unity'nin serile\u015ftirme sistemine derinlemesine entegre edilmi\u015ftir. Bir ScriptableObject asset'i olu\u015fturuldu\u011funda, Unity onun i\u00e7indeki serile\u015ftirilebilir alanlar\u0131 (public alanlar veya <code>[SerializeField]<\/code> ile i\u015faretlenmi\u015f private\/protected alanlar) otomatik olarak diskte bir dosya olarak kaydeder. Unity'nin serile\u015ftirme sistemi, ScriptableObjects'\u0131 y\u00fckleyip bo\u015faltmay\u0131 ve Edit\u00f6r'de Inspector arac\u0131l\u0131\u011f\u0131yla d\u00fczenlenmesini m\u00fcmk\u00fcn k\u0131lar. Bu, ScriptableObjects'\u0131n \"Asset\" olarak \u00e7al\u0131\u015fma prensibinin temelini olu\u015fturur.\n        <\/li>\n<\/ul>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Oyun geli\u015ftirme s\u00fcrecinde, oyuncular\u0131n ilerlemesini kaydetmek ve bir sonraki oturumda kald\u0131klar\u0131 yerden devam etmelerini sa\u011flamak kritik bir \u00f6neme&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-34198","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Unity&#039;de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler<\/title>\n<meta name=\"description\" content=\"Oyun geli\u015ftirme s\u00fcrecinde, oyuncular\u0131n ilerlemesini kaydetmek ve bir sonraki oturumda kald\u0131klar\u0131 yerden devam etmelerini sa\u011flamak kritik bir \u00f6neme sahiptir. Peki, bu verileri nas\u0131l daha d\u00fczenli, daha esnek ve daha performansl\u0131 bir \u015fekilde y\u00f6netebiliriz? Unity&#039;de oyun verilerini kaydetmenin \u00e7e\u015fitli yollar\u0131 bulunmaktad\u0131r; \u00f6nceki yaz\u0131lar\u0131m\u0131zda PlayerPrefs ve JSON\/Binary serile\u015ftirmesi gibi y\u00f6ntemleri ele alm\u0131\u015ft\u0131k. Bu makalemizde ise, veri y\u00f6netimini tamamen yeni bir seviyeye ta\u015f\u0131yan, tasar\u0131m zaman\u0131 verilerini d\u00fczenlemede e\u015fsiz bir ara\u00e7 olan ScriptableObjects&#039;\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Bu g\u00fc\u00e7l\u00fc Unity \u00f6zelli\u011fi ile oyun verilerinizi kal\u0131c\u0131 ve esnek bir \u015fekilde nas\u0131l saklayaca\u011f\u0131n\u0131z\u0131, tasar\u0131mda kolayl\u0131k ve performansta art\u0131\u015f i\u00e7in ad\u0131m ad\u0131m rehberimizi takip ederek \u00f6\u011frenin.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Unity&#039;de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler\" \/>\n<meta property=\"og:description\" content=\"Oyun geli\u015ftirme s\u00fcrecinde, oyuncular\u0131n ilerlemesini kaydetmek ve bir sonraki oturumda kald\u0131klar\u0131 yerden devam etmelerini sa\u011flamak kritik bir \u00f6neme sahiptir. Peki, bu verileri nas\u0131l daha d\u00fczenli, daha esnek ve daha performansl\u0131 bir \u015fekilde y\u00f6netebiliriz? Unity&#039;de oyun verilerini kaydetmenin \u00e7e\u015fitli yollar\u0131 bulunmaktad\u0131r; \u00f6nceki yaz\u0131lar\u0131m\u0131zda PlayerPrefs ve JSON\/Binary serile\u015ftirmesi gibi y\u00f6ntemleri ele alm\u0131\u015ft\u0131k. Bu makalemizde ise, veri y\u00f6netimini tamamen yeni bir seviyeye ta\u015f\u0131yan, tasar\u0131m zaman\u0131 verilerini d\u00fczenlemede e\u015fsiz bir ara\u00e7 olan ScriptableObjects&#039;\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Bu g\u00fc\u00e7l\u00fc Unity \u00f6zelli\u011fi ile oyun verilerinizi kal\u0131c\u0131 ve esnek bir \u015fekilde nas\u0131l saklayaca\u011f\u0131n\u0131z\u0131, tasar\u0131mda kolayl\u0131k ve performansta art\u0131\u015f i\u00e7in ad\u0131m ad\u0131m rehberimizi takip ederek \u00f6\u011frenin.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-12T14:01:32+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Unity&#8217;de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler\",\"datePublished\":\"2025-11-12T14:01:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/\"},\"wordCount\":5084,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/\",\"name\":\"Unity'de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-12T14:01:32+00:00\",\"description\":\"Oyun geli\u015ftirme s\u00fcrecinde, oyuncular\u0131n ilerlemesini kaydetmek ve bir sonraki oturumda kald\u0131klar\u0131 yerden devam etmelerini sa\u011flamak kritik bir \u00f6neme sahiptir. Peki, bu verileri nas\u0131l daha d\u00fczenli, daha esnek ve daha performansl\u0131 bir \u015fekilde y\u00f6netebiliriz? Unity'de oyun verilerini kaydetmenin \u00e7e\u015fitli yollar\u0131 bulunmaktad\u0131r; \u00f6nceki yaz\u0131lar\u0131m\u0131zda PlayerPrefs ve JSON\/Binary serile\u015ftirmesi gibi y\u00f6ntemleri ele alm\u0131\u015ft\u0131k. Bu makalemizde ise, veri y\u00f6netimini tamamen yeni bir seviyeye ta\u015f\u0131yan, tasar\u0131m zaman\u0131 verilerini d\u00fczenlemede e\u015fsiz bir ara\u00e7 olan ScriptableObjects'\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Bu g\u00fc\u00e7l\u00fc Unity \u00f6zelli\u011fi ile oyun verilerinizi kal\u0131c\u0131 ve esnek bir \u015fekilde nas\u0131l saklayaca\u011f\u0131n\u0131z\u0131, tasar\u0131mda kolayl\u0131k ve performansta art\u0131\u015f i\u00e7in ad\u0131m ad\u0131m rehberimizi takip ederek \u00f6\u011frenin.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Unity&#8217;de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Unity'de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler","description":"Oyun geli\u015ftirme s\u00fcrecinde, oyuncular\u0131n ilerlemesini kaydetmek ve bir sonraki oturumda kald\u0131klar\u0131 yerden devam etmelerini sa\u011flamak kritik bir \u00f6neme sahiptir. Peki, bu verileri nas\u0131l daha d\u00fczenli, daha esnek ve daha performansl\u0131 bir \u015fekilde y\u00f6netebiliriz? Unity'de oyun verilerini kaydetmenin \u00e7e\u015fitli yollar\u0131 bulunmaktad\u0131r; \u00f6nceki yaz\u0131lar\u0131m\u0131zda PlayerPrefs ve JSON\/Binary serile\u015ftirmesi gibi y\u00f6ntemleri ele alm\u0131\u015ft\u0131k. Bu makalemizde ise, veri y\u00f6netimini tamamen yeni bir seviyeye ta\u015f\u0131yan, tasar\u0131m zaman\u0131 verilerini d\u00fczenlemede e\u015fsiz bir ara\u00e7 olan ScriptableObjects'\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Bu g\u00fc\u00e7l\u00fc Unity \u00f6zelli\u011fi ile oyun verilerinizi kal\u0131c\u0131 ve esnek bir \u015fekilde nas\u0131l saklayaca\u011f\u0131n\u0131z\u0131, tasar\u0131mda kolayl\u0131k ve performansta art\u0131\u015f i\u00e7in ad\u0131m ad\u0131m rehberimizi takip ederek \u00f6\u011frenin.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/","og_locale":"tr_TR","og_type":"article","og_title":"Unity'de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler","og_description":"Oyun geli\u015ftirme s\u00fcrecinde, oyuncular\u0131n ilerlemesini kaydetmek ve bir sonraki oturumda kald\u0131klar\u0131 yerden devam etmelerini sa\u011flamak kritik bir \u00f6neme sahiptir. Peki, bu verileri nas\u0131l daha d\u00fczenli, daha esnek ve daha performansl\u0131 bir \u015fekilde y\u00f6netebiliriz? Unity'de oyun verilerini kaydetmenin \u00e7e\u015fitli yollar\u0131 bulunmaktad\u0131r; \u00f6nceki yaz\u0131lar\u0131m\u0131zda PlayerPrefs ve JSON\/Binary serile\u015ftirmesi gibi y\u00f6ntemleri ele alm\u0131\u015ft\u0131k. Bu makalemizde ise, veri y\u00f6netimini tamamen yeni bir seviyeye ta\u015f\u0131yan, tasar\u0131m zaman\u0131 verilerini d\u00fczenlemede e\u015fsiz bir ara\u00e7 olan ScriptableObjects'\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Bu g\u00fc\u00e7l\u00fc Unity \u00f6zelli\u011fi ile oyun verilerinizi kal\u0131c\u0131 ve esnek bir \u015fekilde nas\u0131l saklayaca\u011f\u0131n\u0131z\u0131, tasar\u0131mda kolayl\u0131k ve performansta art\u0131\u015f i\u00e7in ad\u0131m ad\u0131m rehberimizi takip ederek \u00f6\u011frenin.","og_url":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-12T14:01:32+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"13 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Unity&#8217;de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler","datePublished":"2025-11-12T14:01:32+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/"},"wordCount":5084,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/","url":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/","name":"Unity'de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-12T14:01:32+00:00","description":"Oyun geli\u015ftirme s\u00fcrecinde, oyuncular\u0131n ilerlemesini kaydetmek ve bir sonraki oturumda kald\u0131klar\u0131 yerden devam etmelerini sa\u011flamak kritik bir \u00f6neme sahiptir. Peki, bu verileri nas\u0131l daha d\u00fczenli, daha esnek ve daha performansl\u0131 bir \u015fekilde y\u00f6netebiliriz? Unity'de oyun verilerini kaydetmenin \u00e7e\u015fitli yollar\u0131 bulunmaktad\u0131r; \u00f6nceki yaz\u0131lar\u0131m\u0131zda PlayerPrefs ve JSON\/Binary serile\u015ftirmesi gibi y\u00f6ntemleri ele alm\u0131\u015ft\u0131k. Bu makalemizde ise, veri y\u00f6netimini tamamen yeni bir seviyeye ta\u015f\u0131yan, tasar\u0131m zaman\u0131 verilerini d\u00fczenlemede e\u015fsiz bir ara\u00e7 olan ScriptableObjects'\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Bu g\u00fc\u00e7l\u00fc Unity \u00f6zelli\u011fi ile oyun verilerinizi kal\u0131c\u0131 ve esnek bir \u015fekilde nas\u0131l saklayaca\u011f\u0131n\u0131z\u0131, tasar\u0131mda kolayl\u0131k ve performansta art\u0131\u015f i\u00e7in ad\u0131m ad\u0131m rehberimizi takip ederek \u00f6\u011frenin.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/unityde-oyun-verisi-kaydetme-scriptableobjects-ile-guclu-cozumler\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Unity&#8217;de Oyun Verisi Kaydetme: ScriptableObjects ile G\u00fc\u00e7l\u00fc \u00c7\u00f6z\u00fcmler"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34198","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=34198"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34198\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=34198"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=34198"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=34198"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}