Arama butonu
Bu konudaki kullanıcılar: 1 misafir
6
Cevap
2349
Tıklama
0
Öne Çıkarma
Unity Save/Load Sistemini Nası Yapabilirim ?
I
7 yıl
Onbaşı
Konu Sahibi

Merhabalar öncelikle,

Ben bir RPG oyun yapıyorum çoğu kısmı tamamlandı fakat Save/Load sistemini bir türlü yapamadım, isteğim mesela herhangi bir oyunda ilerliyoruz ve kaydedip çıkıyoruz, geri girdiğimizde kaydettiğimiz yerdeyiz topladığımız itemler duruyor öldürdüğümüz düşmanlar geri gelmemiş tamamen kaydettiğimiz yerdeki gibi başlıyoruz, öncelikle denediğim yöntemleri anlatayım;

Oyun ayarlarını .json ile kaydedip okuyabiliyorum hiçbir sorunu yok,
ama bu yöntemi obje array ı ve transform array ı ile denediğimde olmuyor,
.dat meselesini ya güzel anlatan bulamadım yada ben anlamakta güçlük çekiyorum,
.json ile oyuncumun transformunu kaydedip kaydetiğim yerden başlatabiliyorum ama ne itemler geliyor ne öldürdüğüm düşmanlar ölü kalıyor çünkü kaydetmedim ben bunları,
playerprefs ile çok fazla uğraşmam gerekecek tüm objelerin aktifi pasifi için ayrı bir prefs transformları için ayrı floatlar oluşturmam gerkir ki buna da ömür yetmez.

Sorum şu ben oyunu kaydet e bastığımda nasıl bıraktığım gibi aynı şekilde başlayabilirim?


Dat için de bunu denedim ama olmadı

public void Save()
{
/*string jsonData = JsonUtility.ToJson(saveSettings, true);
File.WriteAllText(Application.persistentDataPath + "/save.json", jsonData);*/
BinaryFormatter bf = new BinaryFormatter();
File.Create("filepath").Dispose();
FileStream file = File.Create(Application.persistentDataPath + "/save.dat");

saveSettings.gameobject = _gameobjects;
saveSettings.transforms = _transforms;

bf.Serialize(file, saveSettings);
file.Close();
}

public void Load()
{
/*saveSettings = JsonUtility.FromJson<SaveSettings>(File.ReadAllText(Application.persistentDataPath + "/save.json"));

_transforms = saveSettings.transforms;
_gameobjects = saveSettings.gameobject;*/

if (File.Exists(Application.persistentDataPath + "/save.dat"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/save.dat", FileMode.Open);
PlayerData data = (PlayerData)bf.Deserialize(file);

_gameobjects = saveSettings.gameobject;
_transforms = saveSettings.transforms;

file.Close();
}





< Bu mesaj bu kişi tarafından değiştirildi ImHoly -- 29 Mart 2017; 1:24:15 >

D
7 yıl
Yüzbaşı

Öncelikle direkt olarak Transform, GameObject vs. gibi array kaydetmek iyi bir fikir değil. Onun yerine MobInfo.cs şeklinde bir class açıp, pozisyonu, rotasyonu, hp, mp, dropItems, vs. tüm özellekleri bu class'da tutan serializable bir yapı oluşturman daha mantıklı olacaktır. Aynı şekilde DropInfoTemp.cs ile yere düşen itemleri bu array'da tutabilirsin.

Bunu yapmakta zorlanmanın sebebi OOP mantığını tam kullanamaman sanırım. "OOP Design Pattern" 'leri araştırmanı öneririm.

Ayrıca bir hata daha söyleyeyim, eğer böyle save/load yaparsan, yeni bir değişken eklediğinde veya kaldırdığında, Deserialize edilirken hata verecektir. Bunuda araştırmanı tavsiye ederim. (:

Başarılar...



R
7 yıl
Yarbay

Serialization dünyasına hoşgeldin. Komplike bir konudur , doğru kullanmazsan versiyonlar arası çakışma olur başını çok ağrıtır. O yüzden oynunu programlarken en başta ele alman gerekir bu konuyu. Çünkü oynunu programlarken kullandığın tasarım örgüsünü buna uygun oluşturman gerekir.

Örneğin Karakterin var ve karakterinin bulunduğu odada 5 adet düşman spawn ettin.

Bu sahneyi serialize etmen için

Hangi düşman tipinden kaçar adet bulunduğunu , bu düşmanlarının gerekli ise mevcut statlarını (Can, Stamina vs) Transformunu (Pozisyon Rotasyon) ve diğer hangi serialize etmen gerekli componentler varsa onları. Hatta runtimeda component ekleniyorsa düşmana, onu bile takip etmen gerek.

Array var ise arrayin uzunluğunuda kaydetmen gerekiyor daha sonra deserialize ederken bunları okuyup arrayi dolduracaksın.

Bütün bunlar yüzünden oynunu en başta buna uygun tasarlaman gerekiyor.

Ama gelelim işi kolaylaştıran kısıma

Assetstoreda bunun için çok güzel bi Tool var. https://www.assetstore.unity3d.com/en/#!/content/768

İşini çok kolaylaştıracaktır. Öntanımlı olarak bütün unity typelarını destekliyor kendi custom classlarınıda çok kolay ekleyebiliyorsun. Nested arrayler hariç (Array taşıyan arrayler) Arraylerede destek veriyor. Sequential read write özelliği sayesinde jsona göre çok çok hızlı.

Kolay olmasına rağmen yinede kullanmayı bilmen gerekiyor ama.

Örneğin normalde bu tool Sequential okuma yazma yapar. Yani veriyi hangi sırayla kaydettiysen o sırada okumak zorundasın o yüzden versiyonlar arası çakışma yaşamamak için dikkatli olman lazım bunun için çeşitli çözümler bulunmakta. Onun dışında değişkenlerini tagleyerekde kaydedebilirsin böylece okuma yazma sırası önemsiz oluyor ama buseferde sequentialın hız avantajından feragat etmiş oluyorsun.





< Bu mesaj bu kişi tarafından değiştirildi RISC64 -- 30 Mart 2017; 0:17:1 >
Bu mesaja 2 cevap geldi.
I
7 yıl
Onbaşı
Konu Sahibi

Valla çok zormuş neredeyse oyunun her şeyini yaptım ama kaydetmenin içinden çıkamıyorum ne kadar video varsa izledim kısayolunu bulamadım tek tek tüm pozisyonları rotasyonları aktifleri kaydetmeye kalkarsam işin içinden çıkamam gibi geliyor yokmudur başka bir stratejiniz ne yapmamı önerirsiniz nasıl bir yol izlemeliyim ?



I
7 yıl
Onbaşı
Konu Sahibi

Yasa dışı olarak indirdim ES2 yi bi kurcalayayım diye kullanabilirsem alırım artık kullanımı hakkında yardımcı olur musunuz


Bu mesaja 1 cevap geldi.

Bu mesajda bahsedilenler: @Lordinarius
R
7 yıl
Yarbay

Takıldığın noktada sorabilirsin tabi




Bu mesajda bahsedilenler: @sivasle
F
5 yıl
Yarbay

quote:

Orijinalden alıntı: RISC64

Serialization dünyasına hoşgeldin. Komplike bir konudur , doğru kullanmazsan versiyonlar arası çakışma olur başını çok ağrıtır. O yüzden oynunu programlarken en başta ele alman gerekir bu konuyu. Çünkü oynunu programlarken kullandığın tasarım örgüsünü buna uygun oluşturman gerekir.

Örneğin Karakterin var ve karakterinin bulunduğu odada 5 adet düşman spawn ettin.

Bu sahneyi serialize etmen için

Hangi düşman tipinden kaçar adet bulunduğunu , bu düşmanlarının gerekli ise mevcut statlarını (Can, Stamina vs) Transformunu (Pozisyon Rotasyon) ve diğer hangi serialize etmen gerekli componentler varsa onları. Hatta runtimeda component ekleniyorsa düşmana, onu bile takip etmen gerek.

Array var ise arrayin uzunluğunuda kaydetmen gerekiyor daha sonra deserialize ederken bunları okuyup arrayi dolduracaksın.

Bütün bunlar yüzünden oynunu en başta buna uygun tasarlaman gerekiyor.

Ama gelelim işi kolaylaştıran kısıma

Assetstoreda bunun için çok güzel bi Tool var. https://www.assetstore.unity3d.com/en/#!/content/768

İşini çok kolaylaştıracaktır. Öntanımlı olarak bütün unity typelarını destekliyor kendi custom classlarınıda çok kolay ekleyebiliyorsun. Nested arrayler hariç (Array taşıyan arrayler) Arraylerede destek veriyor. Sequential read write özelliği sayesinde jsona göre çok çok hızlı.

Kolay olmasına rağmen yinede kullanmayı bilmen gerekiyor ama.

Örneğin normalde bu tool Sequential okuma yazma yapar. Yani veriyi hangi sırayla kaydettiysen o sırada okumak zorundasın o yüzden versiyonlar arası çakışma yaşamamak için dikkatli olman lazım bunun için çeşitli çözümler bulunmakta. Onun dışında değişkenlerini tagleyerekde kaydedebilirsin böylece okuma yazma sırası önemsiz oluyor ama buseferde sequentialın hız avantajından feragat etmiş oluyorsun.
Hocam merhaba. Aradan epey bir zaman geçmiş ama şu an forumda sizin bu mesajınızdan başka düzgün bir bilgi içeriği bulamadım. Şu an ben de Unity'de Save & Load işini öğrenmeye çalışıyorum. Ben kabaca Destroy edilen yani sahneden çıkarılan, kaybolan objelerin (düşman da olabilir) save edilmesinin nasıl yapılacağını anlamaya çalışıyorum.

Objelerin konumunu vs. kaydetme kısmını anladım Serialization ile ama bu eksilen veya sonradan oluşturulan objeleri nasıl tutabilirim? Algoritmik açıdan fikir verebilir misiniz?

En basitinden "Roll a Ball" oyununda topladığımız altınların kaybolmasını ele alabiliriz. O oyuna save & load yapacak olsam en basit haliyle altınları Serialization ile nasıl tutabilirim?

Array açacağımı biliyorum da tam kafamda oturtamadım algoritmasını. Daha doğrusu Serialization'u nasıl kullanacağımı bilemedim.

Aklıma gelen algoritma şöyle kabaca:



public GameObject[] destroyed_golds

void Save(){
GameObject[] allGolds = GameObject.FindGameObjectsWithTag("Gold");

for (int i =0; i < allGolds.Lenght; i++)
{
if (allGolds[i].activeSelf==false)
destroyed_gold.Add(allGolds[i])
}
}





Büyük ihtimalle hatalı düşünüyorum. Destroy komutunda obje komple yok olduğundan GameObject.Find çalışır mı bilemiyorum.



DH Mobil uygulaması ile devam edin. Mobil tarayıcınız ile mümkün olanların yanı sıra, birçok yeni ve faydalı özelliğe erişin. Gizle ve güncelleme çıkana kadar tekrar gösterme.