打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Serialize Quaternion or Vector3

Serialize Quaternion or Vector3

It seems like saving your players location and rotation would be pretty common, but I can't seem to find any example of serializing a Quaternion or Vectory3 anywhere.

According to the unity docs here it says the both are serializable but I keep getting the following error "SerializationException: Type UnityEngine.Quaternion is not marked as Serializable." when trying to serialize the following class.

  1. [Serializable]
  2. public class Entity{
  3. public string entityName;
  4. public Quaternion entityRotation;
  5. }

What exactly do you mean by serialize? Do you mean "let Unity serialize the class" or do you mean you tried to serialize the class with .NET's / mono's serialization system?

More context please.

I guess that you try to manually serialize it. In this case, no, it's not compatible with .NET / mono serialization. You have to implement ISerializable and provide a custom serialization method. I'l post an answer ^^

Thanks for the responses. I was hoping I didn't have to manually do this and was just missing something simple in Unity that would automatically serialize these objects.

5条回复

· 添加您的回复
  • 排序: 
9

个解答,截止Cherno · 2015年04月28日 23:46

Here are serializable versions of the Vector3 and Quaternion class, with automatic conversion:

  1. using UnityEngine;
  2. using System;
  3. using System.Collections;
  4. /// <summary>
  5. /// Since unity doesn't flag the Vector3 as serializable, we
  6. /// need to create our own version. This one will automatically convert
  7. /// between Vector3 and SerializableVector3
  8. /// </summary>
  9. [System.Serializable]
  10. public struct SerializableVector3
  11. {
  12. /// <summary>
  13. /// x component
  14. /// </summary>
  15. public float x;
  16. /// <summary>
  17. /// y component
  18. /// </summary>
  19. public float y;
  20. /// <summary>
  21. /// z component
  22. /// </summary>
  23. public float z;
  24. /// <summary>
  25. /// Constructor
  26. /// </summary>
  27. /// <param name="rX"></param>
  28. /// <param name="rY"></param>
  29. /// <param name="rZ"></param>
  30. public SerializableVector3(float rX, float rY, float rZ)
  31. {
  32. x = rX;
  33. y = rY;
  34. z = rZ;
  35. }
  36. /// <summary>
  37. /// Returns a string representation of the object
  38. /// </summary>
  39. /// <returns></returns>
  40. public override string ToString()
  41. {
  42. return String.Format("[{0}, {1}, {2}]", x, y, z);
  43. }
  44. /// <summary>
  45. /// Automatic conversion from SerializableVector3 to Vector3
  46. /// </summary>
  47. /// <param name="rValue"></param>
  48. /// <returns></returns>
  49. public static implicit operator Vector3(SerializableVector3 rValue)
  50. {
  51. return new Vector3(rValue.x, rValue.y, rValue.z);
  52. }
  53. /// <summary>
  54. /// Automatic conversion from Vector3 to SerializableVector3
  55. /// </summary>
  56. /// <param name="rValue"></param>
  57. /// <returns></returns>
  58. public static implicit operator SerializableVector3(Vector3 rValue)
  59. {
  60. return new SerializableVector3(rValue.x, rValue.y, rValue.z);
  61. }
  62. }

Quaternion:

  1. using UnityEngine;
  2. using System;
  3. using System.Collections;
  4. /// <summary>
  5. /// Since unity doesn't flag the Quaternion as serializable, we
  6. /// need to create our own version. This one will automatically convert
  7. /// between Quaternion and SerializableQuaternion
  8. /// </summary>
  9. [System.Serializable]
  10. public struct SerializableQuaternion
  11. {
  12. /// <summary>
  13. /// x component
  14. /// </summary>
  15. public float x;
  16. /// <summary>
  17. /// y component
  18. /// </summary>
  19. public float y;
  20. /// <summary>
  21. /// z component
  22. /// </summary>
  23. public float z;
  24. /// <summary>
  25. /// w component
  26. /// </summary>
  27. public float w;
  28. /// <summary>
  29. /// Constructor
  30. /// </summary>
  31. /// <param name="rX"></param>
  32. /// <param name="rY"></param>
  33. /// <param name="rZ"></param>
  34. /// <param name="rW"></param>
  35. public SerializableQuaternion(float rX, float rY, float rZ, float rW)
  36. {
  37. x = rX;
  38. y = rY;
  39. z = rZ;
  40. w = rW;
  41. }
  42. /// <summary>
  43. /// Returns a string representation of the object
  44. /// </summary>
  45. /// <returns></returns>
  46. public override string ToString()
  47. {
  48. return String.Format("[{0}, {1}, {2}, {3}]", x, y, z, w);
  49. }
  50. /// <summary>
  51. /// Automatic conversion from SerializableQuaternion to Quaternion
  52. /// </summary>
  53. /// <param name="rValue"></param>
  54. /// <returns></returns>
  55. public static implicit operator Quaternion(SerializableQuaternion rValue)
  56. {
  57. return new Quaternion(rValue.x, rValue.y, rValue.z, rValue.w);
  58. }
  59. /// <summary>
  60. /// Automatic conversion from Quaternion to SerializableQuaternion
  61. /// </summary>
  62. /// <param name="rValue"></param>
  63. /// <returns></returns>
  64. public static implicit operator SerializableQuaternion(Quaternion rValue)
  65. {
  66. return new SerializableQuaternion(rValue.x, rValue.y, rValue.z, rValue.w);
  67. }
  68. }

Also check out this guide to Surrogates, very useful:

Link

Here is a ISerializationSurrogate for Vector3:

  1. using System.Runtime.Serialization;
  2. using UnityEngine;
  3. sealed class Vector3SerializationSurrogate : ISerializationSurrogate {
  4. // Method called to serialize a Vector3 object
  5. public void GetObjectData(System.Object obj,
  6. SerializationInfo info, StreamingContext context) {
  7. Vector3 v3 = (Vector3) obj;
  8. info.AddValue("x", v3.x);
  9. info.AddValue("y", v3.y);
  10. info.AddValue("z", v3.z);
  11. Debug.Log(v3);
  12. }
  13. // Method called to deserialize a Vector3 object
  14. public System.Object SetObjectData(System.Object obj,
  15. SerializationInfo info, StreamingContext context,
  16. ISurrogateSelector selector) {
  17. Vector3 v3 = (Vector3) obj;
  18. v3.x = (float)info.GetValue("x", typeof(float));
  19. v3.y = (float)info.GetValue("y", typeof(float));
  20. v3.z = (float)info.GetValue("z", typeof(float));
  21. obj = v3;
  22. return obj; // Formatters ignore this return value //Seems to have been fixed!
  23. }
  24. }

You can include the Surrogate in your formatter like this:

  1. BinaryFormatter bf = new BinaryFormatter();
  2. // 1. Construct a SurrogateSelector object
  3. SurrogateSelector ss = new SurrogateSelector();
  4. Vector3SerializationSurrogate v3ss = new Vector3SerializationSurrogate();
  5. ss.AddSurrogate(typeof(Vector3),
  6. new StreamingContext(StreamingContextStates.All),
  7. v3ss);
  8. // 2. Have the formatter use our surrogate selector
  9. bf.SurrogateSelector = ss;

Why the hell are Vector3 and Quaternion of Unity non-serializable?!

^ What? Double negative much?

@Cherno lol didn't notice that, fixed, thanks

All of the Unity-specific classes are non-serializable. Check the comments under the OP, where the differences between Unity and .NET serialization are explained.

3

个解答,截止Voxel-Busters · 2015年08月07日 12:03

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.

1

个解答,截止aeroson · 2016年01月04日 11:34

0

个解答,截止Bunny83 · 2015年04月28日 20:09

In case you talk about .NET / mono serialization you have to implement the ISerializable interface like this:

  1. using System.Runtime.Serialization;
  2. public class Entity : ISerializable
  3. {
  4. public string entityName;
  5. public Quaternion entityRotation;
  6. public Entity(SerializationInfo info, StreamingContext context)
  7. {
  8. entityName = info.GetString("name");
  9. entityRotation.x = info.GetSingle("RotationX");
  10. entityRotation.y = info.GetSingle("RotationY");
  11. entityRotation.z = info.GetSingle("RotationZ");
  12. entityRotation.w = info.GetSingle("RotationW");
  13. }
  14. public void GetObjectData(SerializationInfo info, StreamingContext context)
  15. {
  16. info.AddValue("name", entityName);
  17. info.AddValue("RotationX", entityRotation.x);
  18. info.AddValue("RotationY", entityRotation.y);
  19. info.AddValue("RotationZ", entityRotation.z);
  20. info.AddValue("RotationW", entityRotation.w);
  21. }
  22. }
,截止MidnightStudiosInc · 2015年07月01日 14:58

GameObject Serializer Pro serializes Vector3, Quaternion, and much more. Unlike BinaryFormatter it is forward-compatable with future versions of .Net/Mono. It's also much more efficient than XmlSerializer.

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Blog: Beautiful maths simplification: quaternion from two vectors – Lol Engine
unity3d 平滑看向的脚本
Implementing Serializable
ABAP和Java的tag(marker) interface
深入浅出.NET中的序列化(Serialization)
Unity3d中四元数的使用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服