Home > Mobile >  Read coordinates from txt file in Unity3D
Read coordinates from txt file in Unity3D

Time:01-20

i've just started to learn unity and i'm having some troubles to go ahead with my exercises. I need to move 2 cars using coordinates stored in a .txt file called "positions.txt". The cars have to move at the same time. Inside the "cartesian" list there are numbers which have to be splitted in groups of 4 (time, x, y, z).

I'd like to create 2 arrays for each car: a time array and a Vector3 array.

First of all, i need to read the file and store the numbers in the arrays. I found several options and i tried this one without success: https://allison-liem.medium.com/unity-reading-external-json-files-878ed0978977 Which approach should i follow?

Thank you.

File "positions.txt"

[
  {
    "id":"car_1",
    "position":{
      "cartesian":[
        1,0,0,0,
        2,0,0,2,
        3,1,0,3,
        4,1,0,6,
        5,2,1,9,
        6,2,0,11,
        7,3,1,13,
        8,3,0,15,
        9,3,1,18,
        10,4,1,20]
    }
  },
  {
    "id":"car_2",
    "position":{
      "cartesian":[
        1,0,0,0,
        2,0,0,2,
        3,1,0,3,
        4,1,0,6,
        5,2,1,9,
        6,2,0,11,
        7,3,1,13,
        8,3,0,15,
        9,3,1,18,
        10,4,1,20]
    }
  }
]

CodePudding user response:

So first of all you have a JSON so see Serialize and Deserialize Json and Json Array in Unity

I would recommend the Newtonsoft Json.NET package and do e.g.

[Serializable]
public class Position
{
    // you can also go for array if you liked
    // in JSON it is the same
    public List<int> cartesian;
}

[Serializable]
public class Car
{
    public string id;
    public Position position;
}

and then

var json = File.RealAllText(FILEPATH);
// again could also go for array here
List<Car> cars = JsonConvert.DeserializeObject<List<Car>>(json);

However, the cartesian arrays are a bit "stupid" - have in mind that once this is handled as a list/array there are no line breaks and no good meaning for your redundant indices (1, 2, 3, 4, ...) at the beginning of each set.

I'd like to create 2 arrays for each car: a time array and a Vector3 array.

his wouldn't make sense in my eyes - if something that information clearly belongs coupled together so splitting it into individual arrays would be bad.

Either way you will have to manually extract your values when iterating over the list/array

  • Go in sets of 4 items
  • Ignore the first - it seems to be a redundant index
  • take the last three items and fill them into x,y,z of a vector

like e.g.

[Serializable]
public class Position
{
    // you can also go for array if you liked
    // in JSON it is the same
    public List<int> cartesian;

    public List<Vector3> GetPositions()
    {
        var count = cartesian.Count / 4;
        var result = new List<Vector3>(count);

        for(var resultIndex = 0; resultIndex < count; resultIndex  )
        {
            var cartesianIndex = resultIndex * 4;
            var position = new Vector3(cartesian[cartesianIndex   1], cartesian[cartesianIndex   2], cartesian[cartesianIndex   3]);
            result.Add(position);
        }
    }
}

or if you actually need also that first value I would use a custom type like e.g.

public readonly struct TimeFrame
{
    public int Time { get; }
    public Vector3 Position { get; }

    public TimeFrame(int time, Vector position)
    {
        Time = time;
        Position = position;
    }
}

and then adjust accordingly

[Serializable]
public class Position
{
    // you can also go for array if you liked
    // in JSON it is the same
    public List<int> cartesian;

    public List<TimeFrame> GetPositions()
    {
        var count = cartesian.Count / 4;
        var result = new List<TimeFrame>(count);

        for(var resultIndex = 0; resultIndex < count; resultIndex  )
        {
            var cartesianIndex = resultIndex * 4;
            var time = cartesian[cartesianIndex];
            var position = new Vector3(cartesian[cartesianIndex   1], cartesian[cartesianIndex   2], cartesian[cartesianIndex   3]);
            result.Add(new TimeFrame(time, position));
        }
    }
}

CodePudding user response:

I saw that the medium article you're referring to uses Unity's built in JSON parsing library which does not support array parsing, as pointed out by this answer here https://stackoverflow.com/a/36244111/13489126.

That is the reason why your approach was not working.

I would recommend you to use Newtonsoft Json Parser instead of Unity's.

  • Related