MonoBehaviourSerializer.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEditor;
  4. using UnityEngine;
  5. using Newtonsoft.Json.Linq;
  6. namespace AssetBank.Editor.SceneSchema.Internal
  7. {
  8. public static class MonoBehaviourSerializer
  9. {
  10. public static IDictionary<string, JToken> Serialize(MonoBehaviour obj)
  11. {
  12. var fields = new Dictionary<string, JToken>();
  13. if (obj == null) return fields;
  14. var serializedObject = new SerializedObject(obj);
  15. var property = serializedObject.GetIterator();
  16. property.NextVisible(true);
  17. while (property.NextVisible(false))
  18. {
  19. fields[property.name] = ConvertPropertyToJToken(property);
  20. }
  21. return fields;
  22. }
  23. private static JToken ConvertPropertyToJToken(SerializedProperty prop)
  24. {
  25. if (prop.depth > 10) return JValue.CreateNull();
  26. switch (prop.propertyType)
  27. {
  28. // Basic Types
  29. case SerializedPropertyType.Integer: return new JValue(prop.longValue);
  30. case SerializedPropertyType.Boolean: return new JValue(prop.boolValue);
  31. case SerializedPropertyType.Float: return new JValue(prop.doubleValue);
  32. case SerializedPropertyType.String: return new JValue(prop.stringValue);
  33. case SerializedPropertyType.Enum: return new JValue(prop.enumDisplayNames[prop.enumValueIndex]);
  34. // Unity-specific Structs
  35. case SerializedPropertyType.Color:
  36. var c = prop.colorValue;
  37. return new JObject { { "r", c.r }, { "g", c.g }, { "b", c.b }, { "a", c.a } };
  38. case SerializedPropertyType.Vector2:
  39. var v2 = prop.vector2Value;
  40. return new JObject { { "x", v2.x }, { "y", v2.y } };
  41. case SerializedPropertyType.Vector3:
  42. var v3 = prop.vector3Value;
  43. return new JObject { { "x", v3.x }, { "y", v3.y }, { "z", v3.z } };
  44. case SerializedPropertyType.Vector4:
  45. var v4 = prop.vector4Value;
  46. return new JObject { { "x", v4.x }, { "y", v4.y }, { "z", v4.z }, { "w", v4.w } };
  47. case SerializedPropertyType.Quaternion:
  48. var q = prop.quaternionValue;
  49. return new JObject { { "x", q.x }, { "y", q.y }, { "z", q.z }, { "w", q.w } };
  50. case SerializedPropertyType.Rect:
  51. var r = prop.rectValue;
  52. return new JObject { { "x", r.x }, { "y", r.y }, { "width", r.width }, { "height", r.height } };
  53. case SerializedPropertyType.Bounds:
  54. var b = prop.boundsValue;
  55. return new JObject { { "center", new JObject { { "x", b.center.x }, { "y", b.center.y }, { "z", b.center.z } } }, { "size", new JObject { { "x", b.size.x }, { "y", b.size.y }, { "z", b.size.z } } } };
  56. // Reference Types
  57. case SerializedPropertyType.ObjectReference:
  58. return SerializeObjectReference(prop.objectReferenceValue);
  59. // Arrays and Lists
  60. case SerializedPropertyType.Generic when prop.isArray:
  61. var array = new JArray();
  62. for (var i = 0; i < prop.arraySize; i++)
  63. {
  64. array.Add(ConvertPropertyToJToken(prop.GetArrayElementAtIndex(i)));
  65. }
  66. return array;
  67. // Nested Serializable Classes
  68. case SerializedPropertyType.Generic:
  69. var nestedObject = new JObject();
  70. var copy = prop.Copy();
  71. var end = copy.GetEndProperty();
  72. copy.NextVisible(true);
  73. while (!SerializedProperty.EqualContents(copy, end))
  74. {
  75. nestedObject[copy.name] = ConvertPropertyToJToken(copy);
  76. copy.NextVisible(false);
  77. }
  78. return nestedObject;
  79. default:
  80. return new JValue($"Unsupported Type: {prop.propertyType}");
  81. }
  82. }
  83. private static JToken SerializeObjectReference(UnityEngine.Object obj)
  84. {
  85. if (obj == null) return JValue.CreateNull();
  86. var reference = new JObject
  87. {
  88. ["type"] = obj.GetType().FullName
  89. };
  90. if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _))
  91. {
  92. reference["guid"] = guid;
  93. reference["assetPath"] = AssetDatabase.GUIDToAssetPath(guid);
  94. }
  95. else
  96. {
  97. reference["scene_object_id"] = EditorUtilities.GetLocalFileID(obj);
  98. }
  99. return reference;
  100. }
  101. }
  102. }