如何将场景中的游戏对象位置写入 json 文件?

时间:2021-05-07 01:13:00

标签: json unity3d

在单击按钮时,我正在加载函数 WriteJsonForLevel()。我已经放置了三个标签名称为“RedCoin”的游戏对象,我想将游戏对象的位置写入 JSON 文件。我可以得到对象的位置,但它都被覆盖了。我只能看到最后一个 GameObject 位置(即循环完成) enter image description here

public List<GameObject> levelObjects;
 public string level;
 public Vector3 pos;
 // Start is called before the first frame update
 void Start()
 {
     levelObjects = new List<GameObject>();
     
 }
 // Update is called once per frame
 void Update()
 {
     
 }
 public void WritejsonForAll()
 {
     WriteJsonForLevel();
 }
 public void WriteJsonForLevel()
 {
  
    /* FileStream fs = new FileStream(Application.dataPath + "/sample.json",FileMode.Create);
     StreamWriter writer= new StreamWriter(fs);*/
     GameObject[] coinObjRed = GameObject.FindGameObjectsWithTag("RedCoin");
     putAllObjectInList(coinObjRed);
   
     
   
     
 }
 public void putAllObjectInList(GameObject[] p)
 {
     string path = Application.dataPath + "/text.json";
    foreach (GameObject q in p)
     {
         levelObjects.Add(q);
     }
     for (int i = 0; i < levelObjects.Count; i++)
     {
         GameObject lvlObj = levelObjects[i];
         Vector3 pos = lvlObj.transform.position;
         string posOutput = JsonUtility.ToJson(pos);
          File.WriteAllText(path,posOutput);
          Debug.Log("position:" + posOutput);
 
     }
 }
}

1 个答案:

答案 0 :(得分:0)

您正在使用 WriteAllText,它将 overwrite the file every time it is called。由于它每次在循环中都会覆盖,因此它只会将最后一个对象写入文件,因为之前的所有其他写入都会被覆盖。我会考虑制作一个序列化的数据类,将数据分配给它,将其转换为 JSON 字符串然后保存。

// stores individual locations for saving
[System.Serializable]
public class IndividualLocation
{
    public IndividualLocation(Vector3 pos)
    {
        xPos = pos.x;
        yPos = pos.y;
        zPos = pos.z;
    }
    
    public float xPos;
    public float yPos;
    public float zPos;
}

// stores all game locations for saving
[System.Serializable]
public class AllGameLocations
{
    public List<IndividualLocation> Locations = new List<IndividualLocation>();
}

public void PutAllObjectInList(in GameObject[] p)
{ 
    string path = Application.dataPath + "/text.json";

    // create a new object to write to
    AllGameLocations data = new AllGameLocations();
    
    // iterate the objects adding each to our structure
    foreach(GameObject obj in p)
    {
        data.Locations.Add(new IndividualLocation(obj.transform.position));
    }
    
    // now that the data is filled, write out to the file
    File.WriteAllText(path, JsonUtility.ToJson(AllGameLocations));
}

如果您需要有关如何正确加载数据的片段,我可以添加一个。

编辑:这是一个加载片段

public void LoadJSONObject()
{
    string path = Application.dataPath + "/text.json"; 
    
    // if the file path or name does not exist
    if (!Directory.Exists(Path.GetDirectoryName(path)))
    {
        Debug.LogWarning("File or path does not exist! " + path);
        return
    }

    // load in the save data as byte array
    byte[] jsonDataAsBytes = null;

    try
    {
        jsonDataAsBytes = File.ReadAllBytes(path);
        Debug.Log("<color=green>Loaded all data from: </color>" + path);
    }
    catch (Exception e)
    {
        Debug.LogWarning("Failed to load data from: " + path);
        Debug.LogWarning("Error: " + e.Message);
        return;
    }

    if (jsonDataAsBytes == null)
        return;

    // convert the byte array to json
    string jsonData;

    // convert the byte array to json
    jsonData = Encoding.ASCII.GetString(jsonDataAsBytes);

    // convert to the specified object type
    AllGameLocations returnedData;
    
    JsonUtility.FromJsonOverwrite<AllGameLocations>(jsonData, AllGameLocations);
    
    // use returnedData as a normal object now
    float firstObjectX = returnedData.Locations[0].xPos;
    }
}

让我知道 Load 是否有效,只是输入未经测试。还添加了一些错误处理以确保数据存在且负载正常工作。