RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / user-592598

Kostyan_Sigaev's questions

Martin Hope
Kostyan_Sigaev
Asked: 2024-08-22 20:30:59 +0000 UTC

如何从XML读取数据?

  • 6

我将一些 Unity 场景对象保存到 XML 文件中,以便随时加载此状态并继续游戏。保存到文件没有问题,但读取很糟糕 - 代码将 XML 读取到结构中的第一个结束对象,然后完成读取,尽管这还不到整个文件的 1%。这是一个没有组件等的示例文件:

<?xml version="1.0"?>
<ArrayOfSerializableObject xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SerializableObject>
    <Name>1</Name>
    <Tag></Tag>
    <Position></Position>
    <Rotation></Rotation>
    <Scale></Scale>
    <Children>
      <SerializableObject>
        <Name>2</Name>
        <Tag></Tag>
        <Position></Position>
        <Rotation></Rotation>
        <Scale></Scale>
        <Children>
          <SerializableObject>
            <Name>3</Name>
            <Tag></Tag>
            <Position></Position>
            <Rotation></Rotation>
            <Scale></Scale>
            <Children>
              <SerializableObject>
              <Name>4</Name>
              <Tag></Tag>
              <Position></Position>
              <Rotation></Rotation>
              <Scale></Scale>
              <Children />
              <Components></Components>
            </Children>
            <Components></Components>
          </SerializableObject>
          <SerializableObject>
            <Name>5</Name>
            <Tag></Tag>
            <Position></Position>
            <Rotation></Rotation>
            <Scale></Scale>
            <Children />
            <Components></Components>
          </SerializableObject>
        </Children>
        <Components></Components>
      </SerializableObject>
    </Children>
    <Components />
  </SerializableObject>
</ArrayOfSerializableObject>

结果,我将收到以下结构中的对象:

-1
--2
---3
----4

5 及以后将不再被读取,因为代码应该到达文件末尾。

事实上,这里是保存和读取代码本身(或者更正确地说,是它的一个片段):

using System.Collections.Generic;
using System;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;
using System.Collections;

[Serializable]
public class SerializableObject
{
    public string Name;
    public string Tag;
    public Vector3 Position;
    public Quaternion Rotation;
    public Vector3 Scale;
    public List<SerializableObject> Children = new List<SerializableObject>();
    public List<SerializableComponent> Components = new List<SerializableComponent>();
}

[Serializable]
public class SerializableComponent
{
    public string TypeName;
    public SerializableDictionary Properties = new SerializableDictionary();
}

[Serializable]
public class SerializableDictionary : IXmlSerializable
{
    public Dictionary<string, string> Dictionary = new Dictionary<string, string>();

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        reader.Read();
        while(reader.NodeType != System.Xml.XmlNodeType.EndElement)
        {
            string key = reader.GetAttribute("Key");
            string value = reader.GetAttribute("Value");
            Dictionary.Add(key, value);
            reader.Read();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        foreach(var kvp in Dictionary)
        {
            writer.WriteStartElement("Item");
            writer.WriteAttributeString("Key", kvp.Key);
            writer.WriteAttributeString("Value", kvp.Value);
            writer.WriteEndElement();
        }
    }
}

public class SaveLoadManager : MonoBehaviour
{
    public Transform rootObject;

    public string path, sceneName;

    private List<SerializableObject> loadedData;

    void Awake()
    {
#if UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX
        path = System.IO.Path.GetFullPath(System.IO.Path.Combine(Application.dataPath, "..", "..", "Files", "Saves", sceneName, "savefile.xml"));
#else
        string documentsPath =  System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
        path = System.IO.Path.GetFullPath(System.IO.Path.Combine(documentsPath, "MTS", "Files", "Saves", sceneName, "savefile.xml"));
#endif
    }

    // Сохранение
    public void SaveToXML()
    {
        List<SerializableObject> data = new List<SerializableObject>();
        foreach(Transform child in rootObject)
        {
            data.Add(SaveObject(child));
        }

        XmlSerializer serializer = new XmlSerializer(typeof(List<SerializableObject>));
        using(FileStream stream = new FileStream(path, FileMode.Create))
        {
            serializer.Serialize(stream, data);
        }
    }

    private SerializableObject SaveObject(Transform obj)
    {
        SerializableObject serializableObject = new SerializableObject
        {
            Name = obj.name,
            Tag = obj.tag,
            Position = obj.localPosition,
            Rotation = obj.localRotation,
            Scale = obj.localScale
        };

        foreach(Component component in obj.GetComponents<Component>())
        {
            if(component.GetType() != typeof(Transform))
            {
                serializableObject.Components.Add(SaveComponent(component));
            }
        }

        foreach(Transform child in obj)
        {
            serializableObject.Children.Add(SaveObject(child));
        }

        return serializableObject;
    }

    private SerializableComponent SaveComponent(Component component)
    {
        SerializableComponent serializableComponent = new SerializableComponent
        {
            TypeName = component.GetType().AssemblyQualifiedName
        };

        foreach(var field in component.GetType().GetFields())
        {
            if(field.IsPublic)
            {
                serializableComponent.Properties.Dictionary[field.Name] = field.GetValue(component)?.ToString();
            }
        }

        return serializableComponent;
    }

    // Загрузка
    public void LoadFromXML()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(List<SerializableObject>));
        using(FileStream stream = new FileStream(path, FileMode.Open))
        {
            loadedData = (List<SerializableObject>)serializer.Deserialize(stream);
        }

        foreach(Transform child in rootObject)
        {
            Destroy(child.gameObject);
        }

        foreach(var data in loadedData)
        {
            LoadObject(data, rootObject);
        }
    }

    private void LoadObject(SerializableObject data, Transform parent)
    {
        GameObject obj = new GameObject(data.Name);
        obj.tag = data.Tag;
        obj.transform.SetParent(parent);
        obj.transform.localPosition = data.Position;
        obj.transform.localRotation = data.Rotation;
        obj.transform.localScale = data.Scale;

        foreach(var childData in data.Children)
        {
            LoadObject(childData, obj.transform);
        }
    }
}
c#
  • 2 个回答
  • 104 Views

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5