繁体   English   中英

在Unity HoloLens项目中读取XML文件:在Editor中工作,而不在已部署项目中工作

[英]Reading XML files in a Unity HoloLens project : works in Editor, not in deployed project

我正在尝试保存并加载自定义类“ Animation”(四元数列表,ID的int值和指示要动画的游戏对象的int值),并且保存部分在HoloLens上效果很好,但是由于某些原因,加载部分只能在PC上运行。 在HoloLens上,它返回错误:“ XML文档(2,2)中存在错误。”

我尝试对文件使用StreamingAssets而不是'persistentDataPath',但是在HoloLens上,我再次收到一条错误消息,该错误解释了对该文件的访问被拒绝。

我也尝试过使用TextReader和StreamReader加载“动画”,但结果完全相同。

我也尝试过使用StreamWriter编写“动画”,但是结果也没有改变。

我已经加入了负责编写和加载XML文件的类的代码,以及“ SaveAnimation”函数每次成功编写的示例。

任何想法可能是什么问题? 我很确定问题在于如何编写XML文件,但是我似乎找不到解决方案。

保存/加载类的代码:

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

public class AnimationSaverLoader : MonoBehaviour {

    private string baseFilename = "animation";

    private string path;

    public bool SaveAnimation(Animation animation)
    {
        int animationID = animation.AnimationID;
        path = Path.GetFullPath(Path.Combine(Application.persistentDataPath, baseFilename + animationID + ".xml"));

        try
        {
            using (FileStream writer = new FileStream(path, FileMode.Create))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Animation));
                serializer.Serialize(writer, animation);
            }
            return true;
        }
        catch (System.Exception e)
        {
            Debug.LogWarning("Error saving animation : " + e.Message);
            return false;
        }
    }

    public Animation LoadAnimation(int animationID)
    {
        path = Path.GetFullPath(Path.Combine(Application.persistentDataPath, baseFilename + animationID + ".xml"));
        Animation deserialized = null;

        try
        {
            using (FileStream reader = File.Open(path, FileMode.Open))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Animation));
                deserialized = (Animation)serializer.Deserialize(reader);
            }
        }
        catch (System.Exception e)
        {
            Debug.LogWarningFormat("Error loading animation : {0}", e.Message);
        }

        Debug.LogFormat("deserialized is null : {0}", deserialized == null);

        return deserialized;
    }

还有“ SaveAnimation”函数的XML输出示例:

<?xml version="1.0" encoding="utf-8"?>
<Animation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <nbAnimatables>7</nbAnimatables>
  <animationID>1</animationID>
  <points>
    <ArrayOfQuaternion>
      <Quaternion>
        <x>0</x>
        <y>0</y>
        <z>0</z>
        <w>1</w>
        <eulerAngles>
          <x>-0</x>
          <y>0</y>
          <z>0</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>0</x>
        <y>0</y>
        <z>0</z>
        <w>1</w>
        <eulerAngles>
          <x>-0</x>
          <y>0</y>
          <z>0</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>-0</x>
        <y>-0</y>
        <z>-0</z>
        <w>1</w>
        <eulerAngles>
          <x>-0</x>
          <y>0</y>
          <z>0</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>-0.229409814</x>
        <y>0.0272422452</y>
        <z>-0.114730783</z>
        <w>0.966160357</w>
        <eulerAngles>
          <x>334.0847</x>
          <y>6.722004</y>
          <z>344.9074</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>-0.0120867919</x>
        <y>0.009940858</y>
        <z>-0.0253626034</z>
        <w>0.9995558</w>
        <eulerAngles>
          <x>358.644348</x>
          <y>1.17417169</y>
          <z>357.0791</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>0.2436451</x>
        <y>-0.03456776</y>
        <z>0.0332907774</z>
        <w>0.9686763</w>
        <eulerAngles>
          <x>28.3156128</x>
          <y>356.695343</y>
          <z>3.10282016</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>-0.0274707</x>
        <y>-0.004143617</y>
        <z>0.0005820858</z>
        <w>0.9996139</w>
        <eulerAngles>
          <x>356.852</x>
          <y>359.5228</y>
          <z>0.0798406</z>
        </eulerAngles>
      </Quaternion>
    </ArrayOfQuaternion>
    <ArrayOfQuaternion>
      <Quaternion>
        <x>-0</x>
        <y>-0</y>
        <z>0.5602086</z>
        <w>0.8283516</w>
        <eulerAngles>
          <x>-0</x>
          <y>-0</y>
          <z>68.14045</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>0</x>
        <y>0</y>
        <z>0</z>
        <w>1</w>
        <eulerAngles>
          <x>-0</x>
          <y>0</y>
          <z>0</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>-0</x>
        <y>-0</y>
        <z>-0</z>
        <w>1</w>
        <eulerAngles>
          <x>-0</x>
          <y>0</y>
          <z>0</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>-0.229409814</x>
        <y>0.0272422452</y>
        <z>-0.114730783</z>
        <w>0.966160357</w>
        <eulerAngles>
          <x>334.0847</x>
          <y>6.722004</y>
          <z>344.9074</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>-0.0120867919</x>
        <y>0.009940858</y>
        <z>-0.0253626034</z>
        <w>0.9995558</w>
        <eulerAngles>
          <x>358.644348</x>
          <y>1.17417169</y>
          <z>357.0791</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>0.243645117</x>
        <y>-0.0345677622</y>
        <z>0.03329078</z>
        <w>0.9686764</w>
        <eulerAngles>
          <x>28.3156128</x>
          <y>356.695343</y>
          <z>3.10282016</z>
        </eulerAngles>
      </Quaternion>
      <Quaternion>
        <x>-0.0274707</x>
        <y>-0.004143617</y>
        <z>0.0005820858</z>
        <w>0.9996139</w>
        <eulerAngles>
          <x>356.852</x>
          <y>359.5228</y>
          <z>0.0798406</z>
        </eulerAngles>
      </Quaternion>
    </ArrayOfQuaternion>
  </points>
</Animation>

编辑:弄清楚“动画”类也将很有用。

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

[XmlRoot("Animation")]
public class Animation {

    [XmlElement("nbAnimatables")]
    public int NbAnimatables { get; set; }
    [XmlElement("animationID")]
    public int AnimationID { get; set; }

    [XmlArray("points")]
    public List<Quaternion[]> Points { get; private set; }

    public Animation()
    {
    }

    public Animation(int nbAnimatables, int animationID)
    {
        this.NbAnimatables = nbAnimatables;
        this.AnimationID = animationID;
        Points = new List<Quaternion[]>();
    }

    public bool AddPoint(Quaternion[] animatableRotations)
    {
        if (animatableRotations.Length == NbAnimatables)
        {
            Points.Add(animatableRotations);
            return true;
        }
        return false;
    }

    public bool OverridePoint(Quaternion[] animatableRotations, int pointIndex)
    {
        if (pointIndex < Points.Count)
        {
            Points[pointIndex] = animatableRotations;
            return true;
        }
        return false;
    }

    public bool RemovePoint(int pointIndex)
    {
        if (pointIndex < Points.Count)
        {
            Points.RemoveAt(pointIndex);
            return true;
        }
        return false;
    }
}

尝试以下操作:

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            XmlWriter writer = XmlWriter.Create(path, settings);
            XmlSerializer serializer = new XmlSerializer(typeof(Animation));
            serializer.Serialize(writer, animation);

我会尝试使用StorageFile API:

Windows.Storage.StorageFolder storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
string fileName = baseFilename + animationID + ".xml");
Windows.Storage.StorageFile sampleFile = await storageFolder.CreateFileAsync(fileName,   Windows.Storage.CreationCollisionOption.ReplaceExisting);
using (var stream = await sampleFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);)
{
    using (var outputStream = stream.GetOutputStreamAt(0))
    {
       XmlSerializer serializer = new XmlSerializer(typeof(Animation));
       serializer.Serialize(stream, animation);
       await outputStream.FlushAsync();
    }
}

有关为UWP Apps创建,写入和读取文件的更多信息

遵循jdweng的建议,我决定更改编写文件的方式。 我再次尝试了StreamWriter,由于某种原因,它起作用了! 我通过第18行更改了代码:

        using (StreamWriter writer = new StreamWriter(File.Create(path)))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Animation));
            serializer.Serialize(writer, animation);
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM