Serialize/Deserialize (c# xml) a Vector3 type
Hi, I'have this problem. I would like to serialize the position, rotation, name and current scene of a gameObject. But only the object's name and the scene's name (strings) works fine, not the position data (Vector3 type) and rotation data (Quaternion type).
This is the class to be serialized, very simple:
[Serializable]
public class SpaceObjectData
{
[DataMember]
public string sObjectName;
[DataMember]
public Vector3 transformPosition;
[DataMember]
public Quaternion transformRotation;
[DataMember]
public string sceneLocation;
}
This is the code for serialize my class and and save it on file :
public void SetState()
{
// Stream the file with a File Stream. (Note that File.Create() 'Creates' or 'Overwrites' a file.)
FileStream file = File.Create(path);
//Serialize to xml
DataContractSerializer bf = new DataContractSerializer(ObjectData.GetType());
MemoryStream streamer = new MemoryStream();
//Serialize the file
bf.WriteObject(streamer, ObjectData);
streamer.Seek(0, SeekOrigin.Begin);
//Save to disk
file.Write(streamer.GetBuffer(), 0, streamer.GetBuffer().Length);
file.Close();
}
This is the saved file code in the file:
<SpaceObjectData xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/StarShift">
<sObjectName>Sidearal Hawk</sObjectName>
<sceneLocation>SampleScene</sceneLocation>
<transformPosition xmlns:d2p1="http://schemas.datacontract.org/2004/07/UnityEngine">
<kEpsilon>1E-05</kEpsilon><x>-18.3462925</x><y>-2.04236722</y><z>53.03245</z>
</transformPosition>
<transformRotation xmlns:d2p1="http://schemas.datacontract.org/2004/07/UnityEngine">
<eulerAngles><kEpsilon>1E-05</kEpsilon><x>1.756678</x><y>137.321564</y><z>-4.27087542E-07</z>
</eulerAngles><kEpsilon>1E-06</kEpsilon><w>0.363846153</w><x>0.00557816075</x><y>0.931332946</y><z>-0.0142783672</z>
</transformRotation>
</SpaceObjectData>
everything seems OK, all data are saved.
This is the function to read the file and deserialize the stream:
public void GetState()
{
if (System.IO.File.Exists(path))
{
string text = System.IO.File.ReadAllText(path);
using (Stream stream = new MemoryStream())
{
byte[] bytes = Encoding.UTF8.GetBytes(text);
stream.Write(bytes, 0, bytes.Length);
stream.Position = 0;
DataContractSerializer serializer = new DataContractSerializer((ObjectData.GetType()));
ObjectData = (SpaceObjectData)serializer.ReadObject(stream);
}
print(ObjectData.sObjectName); //output OK
print(ObjectData.sceneLocation); //output OK
print(ObjectData.transformPosition); //output wrong (always 0,0,0)
print(ObjectData.transformRotation); //output wrong (always 0,0,0,0)
}
}
Where is that wrong? Why does not it read the Vector3 and Quaternion data and place them in the class? How should I save the Vector3 and Quaternions to be able to deserialize and read them?
Answer by WILEz1975 · Mar 27, 2019 at 10:46 PM
Solved with this structures:
using System;
using UnityEngine;
/// <summary>
/// Since unity doesn't flag the Vector3 as serializable, we
/// need to create our own version. This one will automatically convert
/// between Vector3 and SerializableVector3
/// </summary>
[Serializable]
public struct SerializableVector3
{
/// <summary>
/// x component
/// </summary>
public float x;
/// <summary>
/// y component
/// </summary>
public float y;
/// <summary>
/// z component
/// </summary>
public float z;
/// <summary>
/// Constructor
/// </summary>
/// <param name="rX"></param>
/// <param name="rY"></param>
/// <param name="rZ"></param>
public SerializableVector3(float rX, float rY, float rZ)
{
x = rX;
y = rY;
z = rZ;
}
/// <summary>
/// Returns a string representation of the object
/// </summary>
/// <returns></returns>
public override string ToString()
{
return String.Format("[{0}, {1}, {2}]", x, y, z);
}
/// <summary>
/// Automatic conversion from SerializableVector3 to Vector3
/// </summary>
/// <param name="rValue"></param>
/// <returns></returns>
public static implicit operator Vector3(SerializableVector3 rValue)
{
return new Vector3(rValue.x, rValue.y, rValue.z);
}
/// <summary>
/// Automatic conversion from Vector3 to SerializableVector3
/// </summary>
/// <param name="rValue"></param>
/// <returns></returns>
public static implicit operator SerializableVector3(Vector3 rValue)
{
return new SerializableVector3(rValue.x, rValue.y, rValue.z);
}
}
/// <summary>
/// Since unity doesn't flag the Vector3 as serializable, we
/// need to create our own version. This one will automatically convert
/// between Vector3 and SerializableVector3
/// </summary>
[Serializable]
public struct SerializableQuaternion
{
/// <summary>
/// x component
/// </summary>
public float x;
/// <summary>
/// y component
/// </summary>
public float y;
/// <summary>
/// z component
/// </summary>
public float z;
/// <summary>
/// z component
/// </summary>
public float w;
/// <summary>
/// Constructor
/// </summary>
/// <param name="rX"></param>
/// <param name="rY"></param>
/// <param name="rZ"></param>
/// <param name="rW"></param>
public SerializableQuaternion(float rX, float rY, float rZ,float rW)
{
x = rX;
y = rY;
z = rZ;
w = rW;
}
/// <summary>
/// Returns a string representation of the object
/// </summary>
/// <returns></returns>
public override string ToString()
{
return String.Format("[{0}, {1}, {2},{3}]", x, y, z,w);
}
/// <summary>
/// Automatic conversion from SerializableVector3 to Vector3
/// </summary>
/// <param name="rValue"></param>
/// <returns></returns>
public static implicit operator Quaternion(SerializableQuaternion rValue)
{
return new Quaternion(rValue.x, rValue.y, rValue.z, rValue.w);
}
/// <summary>
/// Automatic conversion from Vector3 to SerializableVector3
/// </summary>
/// <param name="rValue"></param>
/// <returns></returns>
public static implicit operator SerializableQuaternion(Quaternion rValue)
{
return new SerializableQuaternion(rValue.x, rValue.y, rValue.z, rValue.w);
}
}
Thanks to the http://www.unity3dtutorials.it/ community.
Your answer
Follow this Question
Related Questions
How do I specify the origin and end points of the arc1 instantiated line? 0 Answers
How can I create vector fields for use with the new VFX Graph? 3 Answers
Get Face/Triangle size in world space from RaycastHit 0 Answers
Substitute transform.rotation + slerp with transform.rotate and Vector3 0 Answers