- Home /
How can i serialize a Quaternion?
I'm trying to Serialize a Class I made that has a Quaternion in it, but i get this error on run time:
"SerializationException: Type UnityEngine.Quaternion is not marked as Serializable."
After reading this page I understood that Quaternions are only serialized by the Unity's own serializer and not by the one from the System namespace.
So how can i do this?
Would it be good enough to serialize the Quaternion's fields x, y, z, w? or in other words can we save a quaternion as 4 simple values? Is there a better option that anyone knows of?
Check out the code here and see if that helps you:
http://answers.unity3d.com/questions/244867/how-do-i-save-my-objects-position-dynamically-in-a.html
You can try to serialize the Quaternions euler rotation ?
Answer by Aria-Lliane · May 02, 2013 at 09:36 PM
Thank you all, majorly 'whydoidoit' and 'Dracorat' for the replys, meanwhile I solved my problem, using the System Serializer (the hard and long path). So this is how i did it:
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
//my Node class to be serialized
[Serializable]
public class MyClass : ISerializable
{
[NonSerializedAttribute] //dont forget to add this
public Quaternion DIR;
[NonSerializedAttribute] //im serious
public List<Transform> objParts;
public MyClass(Transform[] components, Quaternion vector)
{
DIR = new Quaternion();
DIR = vector;
objParts=new List<Transform>();
foreach(Transform t in components)
{
Transform temp = new GameObject().transform;
temp.rotation = t.rotation;
temp.position = t.position;
objParts.Add(temp);
}
}
//Serialization function (this one gived an headhache x.x).
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("DIRx",DIR.x);
info.AddValue("DIRy",DIR.y);
info.AddValue("DIRz",DIR.z);
info.AddValue("DIRw",DIR.w);
info.AddValue("ObjectCount",objParts.Count);
for(int i=0; i<objParts.Count; i++)
{
info.AddValue("Part"+i+"rotation"+"x",objParts[i].rotation.x);
info.AddValue("Part"+i+"rotation"+"y",objParts[i].rotation.y);
info.AddValue("Part"+i+"rotation"+"z",objParts[i].rotation.z);
info.AddValue("Part"+i+"rotation"+"w",objParts[i].rotation.w);
info.AddValue("Part"+i+"position"+"x",objParts[i].position.x);
info.AddValue("Part"+i+"position"+"y",objParts[i].position.y);
info.AddValue("Part"+i+"position"+"z",objParts[i].position.z);
}
}
//Deserialization constructor (holy cow).
public MyClass(SerializationInfo info, StreamingContext ctxt)
{
//Get the values from info and assign them to the appropriate properties
DIR.x = (float)info.GetValue("DIRx", typeof(float));
DIR.y = (float)info.GetValue("DIRy", typeof(float));
DIR.z = (float)info.GetValue("DIRz", typeof(float));
DIR.w = (float)info.GetValue("DIRw", typeof(float));
int Nparts = (int)info.GetValue("Nparts", typeof(int));
objParts = new List<Transform>();
for(int i=0; i<Nparts; i++)
{
Transform temp = new GameObject().transform;
Vector4 tempv4 = new Vector4();
Vector3 tempv3 = new Vector3();
tempv4.x = (float)info.GetValue("Part"+i+"rotation"+"x", typeof(float));
tempv4.y = (float)info.GetValue("Part"+i+"rotation"+"y", typeof(float));
tempv4.z = (float)info.GetValue("Part"+i+"rotation"+"z", typeof(float));
tempv4.w = (float)info.GetValue("Part"+i+"rotation"+"w", typeof(float));
tempv3.x = (float)info.GetValue("Part"+i+"position"+"x", typeof(float));
tempv3.y = (float)info.GetValue("Part"+i+"position"+"y", typeof(float));
tempv3.z = (float)info.GetValue("Part"+i+"position"+"z", typeof(float));
temp.rotation=new Quaternion(tempv4.x,tempv4.y,tempv4.z,tempv4.w);
temp.position=tempv3;
objParts.Add(temp);
}
}
}
Answer by Aria-Lliane · Apr 13, 2013 at 03:34 AM
Sorry to take so long to reply, I've been reading trough stuff about unity serializer, all your suggestions and stuff, and trying to understand all of the info. And now i have more questions and doubts then when i started.
First of i need to clear things out, I'm not just trying to serialize a quaternion but also lots of other stuff, i just taught that knowing how to serialize a quaternion would be a good start on saving all i need to, this is not exactly for a game, but in my point of view unity is the best place to do it due to several factors.
So the problem is the next, I have an N-ary tree with lots of nodes that i made my own, each node has lot of stuff\information in it, from Quaternions to Transforms. This tree is created and expanded when the program runs, and it runs perfectly, it took me a couple mouths to make it perfect.
But then i came to the problem of when i close my program, the tree vanishes and the next time I run the program I'll need to generate the tree back from the beginning, meaning, I'll never get anywhere with this unless I leave the computer always on for days.
So I started serializing stuff, first I had no idea unity had he's own serializer and as I knew a bit of the System one I started using it, but then I came to the problem in the initial post. So basically if the nodes only had "light" variables it would serialize well and I would have all the code already done, but as I'm trying to save unity variables.... well, I'm kinda stuck.
Like i said, after reading and watching some stuff about this, i now am very confused, and i have no idea how to use unity's serializer in here, or if I'll need to replace all the serialization stuff I had already done.
And so I don't know how to exactly ask for help, but I do feel like I really need it to do this :(
So my best thinking is of making a little example of what I have (in a small scale and without any tree) and ask someone who knows how to just modify it\change it\ remake it in order to work.
So here's the code of an example of what i have (it obviously gives error when trying to serialize the quaternion and transforms):
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
//My saving function
void saveToFile(MyClass obj)
{
Stream stream = File.Open("Memory.mem", FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Serialize(stream, obj);
stream.Close();
}
//my Node class to be serialized
[Serializable]
public class MyClass : ISerializable
{
public Quaternion DIR;
public List<Transform> objParts;
public MyClass(Transform[] components, Quaternion vector)
{
DIR = new Quaternion();
DIR = vector;
objParts=new List<Transform>();
foreach(Transform t in components)
{
Transform temp = new GameObject().transform;
temp.rotation = t.rotation;
temp.position = t.position;
objParts.Add(temp);
}
}
//Serialization function.
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("DIR",DIR);
info.AddValue("objParts",objParts);
}
//Deserialization constructor.
public MyClass(SerializationInfo info, StreamingContext ctxt)
{
//Get the values from info and assign them to the appropriate properties
DIR = (Quaternion)info.GetValue("DIR", typeof(Quaternion));
objParts = (List<Transform>)info.GetValue("objParts", typeof(List<Transform>));
}
}
Unity Serializer has custom support for Quaternions (by saving the x,y,z,w values). But like all reflection serializers it stumbles across structs and can't handle them well - so you have to write special cases (which as I say US does for Vector3, Quaternion etc).
Hello whydoidoit, it's amazing you were the one to answer, cause i've read this page: http://whydoidoit.com/unityserializer/ I liked the vid, and the US looks awsome, but i still dont know how to use it in the code, it seems easy to do a menu and use the saving options of it in game, like you did in the video, but how do i do that in the code? i tried to use the following lines:
[SerializeAll] ins$$anonymous$$d of "[Serializable]" and LevelSerializer.SaveGame(name) in my saveToFile Function ins$$anonymous$$d of the 4 lines i had in it.
The couple functions i have in $$anonymous$$yClass would also become useless.
But this gives me a lot of errors in the US files like this:
O$$anonymous$$, some of the errors where due to the .net 4.0 glitch.
But why am i missing the "Serialization" namespace??? o__o
using Serialization; < The type or namespace name "serialization" could not be found
It's System.Runtime.Serialization.
You can't leave off the first parts.
Dracorat, your coment doesnt make sence, atleast to me, i downloaded the US from the asset-store, it came like that, or are you telling me that each time somone downloads US from the store he\she needs to change its code? It is giving those errors in the US files\classes, not in $$anonymous$$e.
Anyway, i changed it, now it is not finding UnityEditor.... this US is making me have an headhache x.x
#pragma strict < namespace 'UnityEditor' not found
In file Character$$anonymous$$otor.js of US and in many other files
Answer by Voxel-Busters · Jun 08, 2015 at 07:32 AM
You won't be able to serialise Vectors, Colors and Quaternions directly as they are not Serializable classes. But c# allows you to implement serialization extensions classes using ISerializationSurrogate. Check this link for more info https://msdn.microsoft.com/en-us/library/system.runtime.serialization.surrogateselector%28v=vs.110%29.aspx
But if you want to avoid all the trouble and save time, then check out Runtime Serialization for Unity fast and efficient plugin designed to handle serialization of c# class object as well Unity Objects like GameObject, Transform, Textures etc.
Answer by MidnightStudiosInc · Jul 01, 2015 at 02:48 PM
GameObject Serializer Pro can serialize Vectors and Quaternions directly and simply, with much more. It's also much more efficient than XmlSerializer and is forward/backward-compatable (unlike BinarySerializer)
Your answer
Follow this Question
Related Questions
ONE monobehaviour, all serialization!? 0 Answers
Serialize class with serializable fields, 1 Answer
Problem to add a delete method to a saveload script C# 3 Answers
Serialization of custom class 1 Answer
Serialisation... What can, what can't? 2 Answers