Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by jarleyinc · Mar 30, 2021 at 10:20 AM · listsaveloadsave dataforeach

Save / Load List with Prefabs instantiated in the runtime

Hello,

I am currently programming an idle game and have the following problem: In my scene there will be a generator (prefab) from the beginning, which generates money and can be updated. And you can buy new generators. For this purpose, a generator prefab is instantiated and added to the list "Generators", in which the generator from the beginning is already in. Now i want to save and load the game, when the Player leaves / close the game / app and later come back.

How do I get that exactly? I have to collect the datas (int UpgradeLevel, int Multipliers[] and float LastTick (to calculate offline progression)) from each generator in the List or in the scene with a foreach loop and save the datas in a new list, which i save in a json-file. right? And later i instantiate the number of generators in the list and assign them the values ​​from the generators from the list. right? So i understand it so far, but I don't get it implemented.

I already try to code the following for the first part:

 using System;
 using IdleEngine.Sessions;
 using UnityEngine;
 using IdleEngine.Generators;
 using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 
 
 namespace IdleEngine
 {
     public class IdleEngine : MonoBehaviour
     {
         public Session Session;
         string json;
         string json2;
         Generatordata generator;
         Generaldata general;
         public List<Generatordata> generatorList;
 
 
         private void Awake()
         {
             generatorList = new List<Generatordata>();
         }
 
         private void OnEnable()
         {
             Session.CalculateOfflineProgression();
         }
 
         private void OnDisable()
         {
             Session.LastTicks = DateTime.UtcNow.Ticks;
             SaveGeneralJson();
             SaveGeneratorsJson();
         }
 
         public void SaveGeneratorsJson()
         {
             foreach (Generator gObject in GameObject.FindObjectsOfType<Generator>())
             {
                generator = new Generatordata(gObject.Owned, gObject.transform.position, gObject.multipliers);
               generatorList.Add(generator);
             }
 
             json = JsonUtility.ToJson(generatorList);
             File.WriteAllText(Application.persistentDataPath + "\\save.txt", json);
 
         }
 
         public void SaveGeneralJson()
         {
           
             general = new Generaldata(Session.Money, Session.Level, Session.LastTicks);
 
             json2 = JsonUtility.ToJson(general);
             File.WriteAllText(Application.persistentDataPath + "\\savegeneral.txt", json2);
 
         }
     }
 }
 
 
 [Serializable]
 public class Generatordata
 {
     public int UpgradeLevel;
 
     public Multiplier[] Multipliers;
 
     public Vector3 Position;
 
     public Generatordata(int upgradeLevel, Vector3 position, Multiplier[] multipliers)
     {
         this.UpgradeLevel = upgradeLevel;
         this.Multipliers = multipliers;
         this.Position = position;
     }
 }
 
 
 
 [Serializable]
 public class Generaldata
 {
     public double Money;
 
     public double Level;
 
     public long LastTicks;
 
 
     public Generaldata(double money, double level, long lastTicks)
     {
         this.Money = money;
         this.Level = level;
         this.LastTicks = lastTicks;
     }
 }
 

But i´m not sure, if my approach is correct and i also have problems to find the generators in the scene with the foreach-loop and the FindObjectsOfType. The Loop is not executed. I'm already overwhelmed with the first part. So can someone help me and show me how it works correctly? Maybe there is a tutorial for my case or something. That would be awesome.

Thank you very much.

Comment
Add comment · Show 16
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image aardappel156 · Mar 30, 2021 at 10:40 AM 0
Share

But i´m not sure, if my approach is correct and I also have problems to find the generators in the scene with the foreach-loop and the FindObjectsOfType

This approach seems fine. Maybe organize a little bit more. Having different classes handle different function will get things off your $$anonymous$$d

The Loop is not executed.

Elaborate pls

avatar image jarleyinc · Mar 30, 2021 at 01:18 PM 0
Share

@aardappel156 Thank you for your reply.

The Foreach-Loop is not working. So i guess, GameObject.FindObjectsOfType() doesn´t find anything. i also try it with FindGameObjectsWithTag("generator"). The Prefabs have the tag "generator". But this is also not working. But i have read, that FindObjects... is not so good for the performance, so i want to try it directly with my List "List Generators" which is in Session.Generators. That makes more sense anyway, i guess. Like this:

 foreach (Generator gObject in Session.Generators)
             {
                 generator = new Generatordata(gObject.UpgradeLevel, gObject.transform.position, gObject.Multipliers);
                 generatorList.Add(generator);
 
             }

But now i get the following error message:

 MissingReferenceException: The object of type 'Generator' has been destroyed but you are still trying to access it.

When i add

  Debug.Log(gObject.UpgradeLevel);

at the beginning of the foreach loop. it shows me the correct UpgradeLevel of each Generator in my List.

avatar image aardappel156 jarleyinc · Mar 30, 2021 at 01:37 PM 0
Share

can you do debug.log(generator) after

 generator = new Generatordata(gObject.UpgradeLevel, gObject.transform.position, gObject.Multipliers);
avatar image jarleyinc aardappel156 · Mar 30, 2021 at 01:42 PM 0
Share

It´s not working, because

  generator = new Generatordata(gObject.UpgradeLevel, gObject.transform.position, gObject.Multipliers);

is coursing the error. So the code after that will not be executed .

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Richie_V · Apr 02, 2021 at 01:08 AM

You are on the right track, saving to a file will help you later if you want to implement Apple's, Google's or Steam cloud saves, I have a static script that manages saving and loading to the file, you just call it from anywhere and pass the json string, you can also call SaveFileManager.SavedDataExists(SaveFileManager.GENERATOR_DATA_FILENAME) from anywhere to check if there is save data to load.

 using System;
 using System.IO;
 using System.Runtime.Serialization.Formatters.Binary;
 using UnityEngine;
 using System.Collections.Generic;
 
 public static class SaveFileManager
 {
     public const string GENERAL_DATA_FILENAME = "/GeneralData.sav";
     public const string GENERATOR_DATA_FILENAME = "/GeneratorData.sav";
 
     public static void SaveProgress(string stringToSave, string filename)
     {
         Debug.Log("Saving File: " + Application.persistentDataPath + filename);
         Debug.Log(stringToSave);
 
         BinaryFormatter bf = new BinaryFormatter();
         FileStream stream = new FileStream(Application.persistentDataPath + filename, FileMode.Create);
         bf.Serialize(stream, stringToSave);
         stream.Close();
     }
 
     public static string LoadProgress(string filename)
     {
         if (SavedDataExists(filename))
         {
             Debug.Log("Loading File: " + Application.persistentDataPath + filename);
 
             BinaryFormatter bf = new BinaryFormatter();
             FileStream stream = new FileStream(Application.persistentDataPath + filename, FileMode.Open);
 
             string data = bf.Deserialize(stream) as string;
 
             Debug.Log(data);
 
             stream.Close();
             return data;
         }
         else
         {
             Debug.LogError("File not found.");
             return null;
         }
     }
 
     public static bool SavedDataExists(string filename)
     {
         return File.Exists(Application.persistentDataPath + filename);
     }
 }

I would also just advice you to not use FindObjectsOfType and just add each generator to a list the moment its created, and remove it when it is removed, not only will it prevent any problems you are having with finding the objects, it will also have better performance and it can be helpful if you ever need to do something to all generators. You could add the list to a static GameManager singleton script, or even just a static list to the Generator class itself, the later would look something like this:

 class Generator : MonoBehaviour
 {
     //Runtime list of all generators, can be accessed from anywhere with Generator.createdGenerators
     public static List<Generator> createdGenerators;
 
     private void Awake()
     {
         createdGenerators.Add(this);
     }
 
     private void OnDestroy()
     {
         createdGenerators.Remove(this);
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by aardappel156 · Apr 04, 2021 at 08:28 PM

Alright, so I'm looking into it. and I have a simple project set up like your git. How does the session class get those generators?

Am talking about this variable

 [SerializeField] public List<Generator> Generators;


Edit

I just dragged it inside session.

But I found it from this thread https://stackoverflow.com/questions/41787091/unity-c-sharp-jsonutility-is-not-serializing-a-list

So apparantly You can't serialize a list but there is a work around. You can add a wrapper class for that

for example :

 [Serializable]
 public class AllGenData
 {
     [SerializeField] public GenData[] datas;
 
     public AllGenData(GenData[] a_GenData) // you can ofcourse use list if you choose so I was testing if array and list have a difference but I don't think there is just modify my code to make it work
     {
         datas = a_GenData;
     }
 }

And with that class you can do this before the write call

             AllGenData save = new AllGenData(generatorList);



debug image

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

121 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Problem with saving and loading game timer 0 Answers

How i can PlayerPrefs List<>? 0 Answers

Save and load serialization problem 0 Answers

How to save and load `List myList`? 1 Answer

A node in a childnode? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges