Hi, I’m trying to save the position of all the trees that have not been chopped down in my world for instantiating on loading a game. Currently, I’m trying to do so by attaching a “SaveTree” script component on all my trees that are still standing (chopped trees will be destroyed) and running a FindObjectsOfType() to get an array of all the trees.
Each SaveTree script contains the tree’s type and position.
public class SaveTree : MonoBehaviour {
public float x;
public float y;
public float z;
public string type;
public void SaveTreeData () {
x = transform.position.x;
y = transform.position.y;
z = transform.position.z;
switch (transform.gameObject.tag)
{
case ("Redwood Tree"):
type = "redwood";
return;
case ("Birch Tree"):
type = "birch";
return;
case ("Beech Tree"):
type = "beech";
return;
case ("Pine Tree"):
type = "pine";
return;
case ("Oak Tree"):
type = "oak";
return;
case ("Maple Tree"):
type = "maple";
return;
}
}
}
And then in my saving script, I get a list of the stored data as such:
// Save trees
var treeList = FindObjectsOfType<SaveTree>();
foreach (SaveTree tree in treeList)
{
tree.SaveTreeData();
}
gameData.trees = treeList;
string jsonData = JsonUtility.ToJson(gameData);
File.WriteAllText(path, jsonData);
In my Game Data class which stores all the data in my game, I reference with this:
[Serializable]
public class GameData {
// Player
public SavePlayer player;
// Trees
public SaveTree[] trees;
}
However, in my JSON save file, all I get are “Instance ID: 14204820” for each tree saved. How can I be able to view each tree’s x y z position and type within the JSON file itself so that I can edit it?
I think you need the serializable attribute. It doesn’t look like they show it in the ToJson example, which may be an oversight. But it shows in the fromJson Unity - Scripting API: JsonUtility.FromJson
Ok, didn’t see it on your SaveTree script, which I thought was needed for Unity’s json. I use json.net, so I can’t say with Unity’s. I just know they require Serializable on their classes.
When you use unity’s built in serialization engine to serialize stuff. It serializes anything that is a UnityEngine.Object (such as MonoBehaviours) as a reference by their reference id.
You can’t do this.
You should use a non unity object as a token. You seem to understand the idea of tokenizing just fine since you have this script storing the current state of the object. The problem is that token is a UnityEngine.Object, we just need to get around that.
Furthermore, I’m going to remove this use of tags for the type of tree. There’s a better way to do that.
So, here we go:
public class TreeController : MonoBehaviour
{
public TreeType type;
public SaveToken Tokenize()
{
var token = new SaveToken();
token.position = this.transform.position;
token.type = this.type;
return token;
}
public void RestoreFromToken(SaveToken token)
{
if(token == null) throw new System.ArgumentNullException("token");
this.transform.position = token.position;
this.type = token.type;
}
public enum TreeType
{
Redwood,
Birch,
Beech,
Pine,
Oak,
Maple
}
[System.Serializable]
public class SaveToken
{
public Vector3 position;
public TreeType type;
}
}
[Serializable]
public class GameData {
// Player
public SavePlayer player;
// Trees
public TreeController.SaveToken[] trees;
}
// Save trees
var treeList = new List<TreeController.SaveToken>();
foreach (var tree in FindObjectsOfType<TreeController>())
{
treeList.Add(tree.Tokenize();
}
gameData.trees = treeList.ToArray();
string jsonData = JsonUtility.ToJson(gameData);
File.WriteAllText(path, jsonData);
Hi, thanks for the detailed reply. I have some (noob) questions that require some clarification if you are willing to do so. Doing some research, it seems that enums are pretty useful in defining the tree type, but how do I assign the tree’s type? Am I missing it somewhere in your script, or is it done through the editor?
Also, regarding restoring of the tree data upon loading the game; how do I go about doing this? You have a restore from token method within your TreeController class, but upon loading the game, there are no trees in the scene to call the method. Do I simply instantiate each tree individually according to the number of trees stored in the JSON file and call their restore token method in sequence? Thanks.
I found json.net to be a lot more flexible in what it can do. Last time I looked it was free on the asset store, but we had bought it a long while back for work.
Unity’s json is suppose to be faster though. I had done a bit of research and there are several articles out there where you can compare the different json serializers.
If you don’t need what json.net offers, stick with Unity’s json. If you find Unity’s doesn’t do what you need, you’ll want something better like json.net.
But you’ll still have an issue with object that inherit from UnityEngine.Object. Though not in the same way. Instead when deserializing json.net doesn’t handle the creation of unity objects correctly. Unity needs to create them since they are objects with 2 parts to them, 1 .net runtime part, and 1 unity engine part on the C++ side.
@Deeblock , I have the same problem. I finally got it to work in the editor using newtonsoft, but when I tried to build it as a uwp project the json wouldn’t save.
Hi i trying to Prefab GameObject basically i make outlesh rush game i working on buy manager when player got o buying platform and player buy any item then this item gameObject save in json file and load when game restart reopen now i stuck on current script is saving single data newly buying item save not save whole player item buy please help me to this problem