Saving / Loading a dictionary

Discussion and help for Easy Save 3
richardm1985
Posts: 9
Joined: Mon Apr 16, 2018 10:12 am

Saving / Loading a dictionary

Post by richardm1985 »

Hi Guys,

Here is what I'm trying to save:
public static Dictionary<Vector2, Building> buildingPositions = new Dictionary<Vector2, Building>();

Here is how I save it:
public static void SaveState()
{
ES3.Save<GameObject>("Buildings", buildingPositions);
}

I've verified the "SaveState()" gets called through debug calls. I've gone into the "EasySave" editor extension and added "Building" to the list of types.

I've checked my persistent data path and verified nothing gets saved, so the load function fails as there is no file.

I am certain I am doing something wrong lol. Can anyone please guide me?

Thank you
richardm1985
Posts: 9
Joined: Mon Apr 16, 2018 10:12 am

Re: Saving / Loading a dictionary

Post by richardm1985 »

Just tested with ES3.Save<int>("int test", 5); and no file was created. I think it's ES getting permission to save??
richardm1985
Posts: 9
Joined: Mon Apr 16, 2018 10:12 am

Re: Saving / Loading a dictionary

Post by richardm1985 »

Found another topic with dictionarys and here is his code:

var file = new ES3File(); // Create an ES3File using the default file name.
file.Save<Dictionary<string,float>>("myDictionary", myDictionary); // Save a dictionary to the ES3File.
file.Sync();

So to save to persistentDataPath, I need to use the ES3File class? What does ES3.Save do then?
User avatar
Joel
Moodkie Staff
Posts: 4848
Joined: Wed Nov 07, 2012 10:32 pm

Re: Saving / Loading a dictionary

Post by Joel »

Hi Richard,

Very strange! It should throw an exception if it doesn't have permission to write, but first you might want to open your persistent data path (Window > Easy Save 3 > Tools > Open Persistent Data Path), and right-click the folder and check that it has write permissions enabled in Properties. I assume you're on Windows 10?

If this doesn't work, would you be able to send me a basic project and instructions which replicate it for you so I can check whether it works or not at my end?

Also note that ES3.Save should work. ES3File is for caching save data.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
richardm1985
Posts: 9
Joined: Mon Apr 16, 2018 10:12 am

Re: Saving / Loading a dictionary

Post by richardm1985 »

Thank you so much Joel for responding so quickly.

It looks like it does have permission as I have a file called "SaveData.ES3", which matches the name of what I have at the "Default Data Path" sorry for my ignorance.

So when I do;

ES3.Save<int>("int test", 5);
ES3.Save<Dictionary<Vector2, Building>>("Buildings", buildingPositions);

I should have two files, one called "int test" and the other called "Buildings"? Or did I miss understand what that string parameter is actually used for?

EDIT:

Should I save a dictionary like this:
ES3.Save<Dictionary<Vector2, Building>>("Buildings", buildingPositions);
or
ES3.Save<GameObject>("Buildings", buildingPositions);
User avatar
Joel
Moodkie Staff
Posts: 4848
Joined: Wed Nov 07, 2012 10:32 pm

Re: Saving / Loading a dictionary

Post by Joel »

Hi Richard,

The first string parameter is the Key, which is used to identify each piece of data in the file (imagine the file is like a Dictionary). If you want to specify the file the data is saved to, you can either:
  • Change the default filename in Window > Easy Save 3 > Settings
  • Or provide the third parameter when calling ES3.Save/Load. i.e. ES3.Save<int>("int test", 5, "myFilename.ext");
If you only need to save the Dictionary itself, then you should use ES3.Save<Dictionary<Vector2, Building>>, as ES3.Save<GameObject> will save all supported Components on the GameObject, which would not be necessary.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
richardm1985
Posts: 9
Joined: Mon Apr 16, 2018 10:12 am

Re: Saving / Loading a dictionary

Post by richardm1985 »

Hi Joel,

Sorry to bother you again, still haven't gotten the load functionality to completely work. Every object that I instantiated on runtime becomes a "Easy Save 3 Game Object" with instructions to use "LoadInto".

How can I get my dictionary to use LoadInto? I want to save a list of buildings a player created. On scene change they all get destroyed including their levels. So I am trying to get the objects to be saved before the scene changes and when it does change back, to load the saved buildings.
User avatar
Joel
Moodkie Staff
Posts: 4848
Joined: Wed Nov 07, 2012 10:32 pm

Re: Saving / Loading a dictionary

Post by Joel »

Hi Richard,

If you're not doing so already, there are instructions regarding saving and loading prefab instances by adding an ES3Prefab script to your objects here: http://docs.moodkie.com/easy-save-3/es3 ... s-prefabs/

This will remove the need for creating your own instances and using LoadInto.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
richardm1985
Posts: 9
Joined: Mon Apr 16, 2018 10:12 am

Re: Saving / Loading a dictionary

Post by richardm1985 »

Thank you for the suggestion and sorry for the late response.

That sounds promising but my mind can't figure out how it's meant to work.

So I have a farm prefab I clicked to have the script attached to it, but how do I actually implement it in the load? My mind is blocked because, I save a dictionary and the entire dictionary holds the key. How will I instantiate a new Farm without specifically declaring a key for it in the first place?

Also I get an error When I am trying to save AGAIN:
ArgumentException: Only types of UnityEngine.Component can be written with this method, but argument given is type of Farm

I have no idea why such a simple common idea is made near impossible by unity.
richardm1985
Posts: 9
Joined: Mon Apr 16, 2018 10:12 am

Re: Saving / Loading a dictionary

Post by richardm1985 »

Just to make sure I am following correctly with why I am getting the duplicate "Easy Save 3 Game Objects";

Here is how I am loading;

public static void LoadState()
{
var test = ES3.Load<Dictionary<Vector2, Building>>("Buildings");

foreach (Vector2 v2 in test.Keys)
{
Building b = test[v2];

if(b.GetType() == typeof(Farm))
{
Debug.Log("b type: " + b.GetType());
Debug.Log(b.gameObject);
Debug.Log("Bs name: " + b.name);
//newFarm.name = b.name;
Debug.Log(farmPrefab);

newFarm = Instantiate(farmPrefab) as Farm;
Debug.Log("Build: " + newFarm);
newFarm.transform.position = v2;
Debug.Log(newFarm.transform.position);
newFarm.level = b.level;
newFarm.levelText = newFarm.GetComponentInChildren<Text>();
}
}
}

The instantiate has nothing to do with ES3, yet when that object is create, a new object is created titled "Easy Save 3 Game Object" and it has a farm script attached to it, so I knew it's generated from this code, just don't know why. If I do this three times, I also get three "Easy Save 3 Game Object".

This definitely feels like it has something to do with my code (probably how I save?), because if I try to save twice, I get that error mentioned in the above code
Post Reply