Сохранить все точки средства визуализации строк как объект в XML-файле

#unity3d #xml-serialization

#unity3d #xml-сериализация

Вопрос:

Я столкнулся с проблемой при сохранении всех точек средства визуализации строк как единого объекта в XML-файле. То, что я пытаюсь сделать, это нарисовать что-то в воздухе с помощью средства визуализации линий и сохранить этот рисунок в виде точек в XML-файле, чтобы воссоздать его. Я могу сохранить все правильно, за исключением того, что каждая точка становится одним объектом, а не генерируется под одним объектом. Ниже приведен мой код:

AirDrawObject.cs

 using UnityEngine;
[System.Serializable]
public class AirDrawObject
{
    public string pointIndex;
    public Vector3 pointPosition;
}
 

XMLDataExporter.cs

 public AirDrawObject newAirDrawObject;
public ObjectDatabase objectDB;

public void SaveFeedback(GameObject parentGameObject)
    {
        Transform[] childObjects = parentGameObject.transform.GetComponentsInChildren<Transform>();
         if (childObjects[i].gameObject.tag == "AirDraw")
            {
                LineRenderer lineRenderer = childObjects[i].gameObject.GetComponent<LineRenderer>();
                int count = lineRenderer.positionCount;
                int[] array = new int[count];
                for (int l = 0; l < array.Length; l  )
                {
                    newAirDrawObject = new AirDrawObject();
                    newAirDrawObject.pointIndex = "Point "   l.ToString();
                    newAirDrawObject.pointPosition = lineRenderer.GetPosition(l);
                    objectDB.airDrawObjectList.Add(newAirDrawObject);
                }
            }
     }
 

XML-файл:

 <airDrawObjectList>
    <AirDrawObject>
      <point>Point 0</point>
      <pointPosition>
        <x>-0.0537847765</x>
        <y>0.03524115</y>
        <z>0.518784344</z>
      </pointPosition>
    </AirDrawObject>
    <AirDrawObject>
      <point>Point 1</point>
      <pointPosition>
        <x>-0.0537847765</x>
        <y>0.03524115</y>
        <z>0.518784344</z>
      </pointPosition>
    </AirDrawObject>
    <AirDrawObject>
      <point>Point 2</point>
      <pointPosition>
        <x>-0.0537847765</x>
        <y>0.03524115</y>
        <z>0.518784344</z>
      </pointPosition>
    </AirDrawObject>
 

Ожидаемый результат:

  <AirDrawObject>
  <point>Point 1</point>
   <pointPosition>
     <x>-0.0537847765</x>
     <y>0.03524115</y>
     <z>0.518784344</z>
   </pointPosition>
  <point>Point 2</point>
  <pointPosition>
    <x>-0.0537847765</x>
    <y>0.03524115</y>
    <z>0.518784344</z>
  </pointPosition>
  <point>Point 3</point>
  <point>Point 4</point>
 </AirDrawObject>
<AirDrawObject>
  ....
</AirDrawObject>
 

Может кто-нибудь сказать мне, что я делаю не так?

Комментарии:

1. Хорошо.. вы создаете отдельные объекты в списке … какова именно ваша цель? Как еще вы хотели бы его сохранить?

2. @derHugo.. Я хочу сохранить все точки одного объекта средства визуализации строк в списке вместо отдельных объектов.. Я знаю, что это может быть глупой ошибкой, но я могу это понять. Я также указал ожидаемый результат, поэтому, пожалуйста, проверьте его

3. Не имеет смысла, как вы его разместили.. вы открываете <point> тег, но закрываете его еще до указания позиции .. таким образом, это будет список чередующихся point pointPosition объектов и …

4. Ооо .. извините за это. Но эта <point> — это просто строка, в которой хранится индекс.

5. Я просто хочу сохранить позиции всех точек только под одним объектом .. это то, чего я хочу достичь..

Ответ №1:

Почему бы просто не создать свой класс

 [Serializable]
[XmlRoot("ObjectDatabase")]
public class ObjectDatabase
{
    [XmlArray("AirDrawList")]
    [XmlArrayItem("AirDraw")]
    public List<XmlAirDraw> AirDrawList = new List<XmlAirDraw>();
}

[Serializable]
public class XmlAirDraw
{
    [XmlArray("points")]
    [XmlArrayItem("point")]
    public List<Vector3> points = new List<Vector3>();
}
 

А затем сохранить как

 public void SaveFeedback(GameObject parentGameObject)
{
    objectDb.AirDrawList.Clear();      

    var lines = parentGameObject.transform.GetComponentsInChildren<LineRenderer>(true);

    foreach (var line in lines)
    {
        if(!line.CompareTag("AirDraw")) continue;

        line.GetPositions(out var linePoints);
        var xmlInstance = new AirDrawInstance
        {
            points = linePoints;
        };  

        objectDb.AirDrawList.Add(newAirDrawObject);
     }
 }
 

Обратите внимание, что я печатаю на смартфоне, но я надеюсь, что идея станет понятной, и это должно генерировать XML, подобный

 <ObjectDataBase>
    <AirDrawList>
        <AirDraw>
            <points>
                <point>
                   <x>-0.0537847765</x>
                   <y>0.03524115</y>
                   <z>0.518784344</z>
                </point>
                <point>
                    <x>-0.0537847765</x>
                    <y>0.03524115</y>
                    <z>0.518784344</z>
                </point> 
                ...   
            </points>
        </AirDraw>
        <AirDraw>  
            <points>
                ...   
            </points>
        </AirDraw> 
        ...   
    </AirDrawList>
</ObjectDataBase>
 

Комментарии:

1. Большое спасибо. Я сделал это примерно так. Позвольте мне опубликовать свою версию.

Ответ №2:

Итак, я понял это сам. Я изменил свой класс для point и airDrawPoint, как показано ниже.

AirDrawPoint.cs

 [System.Serializable]
public class AirDrawPoint
{
    public string index;
    public float X;
    public float Y;
    public float Z;
}
 

AirDrawObject.cs

 [System.Serializable]

public class AirDrawObject
{
    public List<AirDrawPoint> pointList = new List<AirDrawPoint>();
}
 

XMLDataExporter.cs

 if (childObjects[i].gameObject.tag == "AirDraw")
            {
                newAirDrawObject = new AirDrawObject();
                LineRenderer lineRenderer = childObjects[i].gameObject.GetComponent<LineRenderer>();
                int count = lineRenderer.positionCount;
                int[] array = new int[count];
                for (int l = 0; l < array.Length; l  )
                {
                    point = new AirDrawPoint();
                    Vector3 position = lineRenderer.GetPosition(l);
                    point.index = "Point "   l.ToString();
                    point.X = position.x;
                    point.Y = position.y;
                    point.Z = position.z;
                    newAirDrawObject.pointList.Add(point);
                }
                objectDB.airDrawObjectList.Add(newAirDrawObject);
            }