4using System.Runtime.InteropServices;
50public static class GameObjectSerializer
52 public static byte[] SerializeGameObject(GameObject go,
bool recursive =
false)
54 using (var stream =
new MemoryStream())
55 using (var writer =
new BinaryWriter(stream))
57 writer.WriteGameObject(go, recursive);
58 return stream.ToArray();
61 public static GameObject DeserializeGameObject(
byte[] array, Transform wrapper =
null)
63 using (var stream =
new MemoryStream(array))
64 using (var reader =
new BinaryReader(stream))
66 return reader.ReadGameObject(wrapper);
71public static class BinaryReaderWriterUnityExt
73 public static T RbAaA<T>(
byte[] data,
int Adress) where T :
struct
76 ByteSize = Marshal.SizeOf(typeof(T));
77 byte[] buffer =
new byte[ByteSize];
78 System.Array.Copy(data, Adress, buffer, 0, buffer.Length);
79 return BATTY<T>(buffer);
81 private static T BATTY<T>(
byte[] bytes) where T :
struct
83 var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
86 return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
93 public static void WriteVector2(
this BinaryWriter aWriter, Vector2 aVec)
95 aWriter.Write(aVec.x); aWriter.Write(aVec.y);
97 public static Vector2 ReadVector2(
this BinaryReader aReader)
99 return new Vector2(aReader.ReadSingle(), aReader.ReadSingle());
101 public static void WriteVector3(
this BinaryWriter aWriter, Vector3 aVec)
103 aWriter.Write(aVec.x); aWriter.Write(aVec.y); aWriter.Write(aVec.z);
105 public static Vector3 ReadVector3(
this BinaryReader aReader)
107 return new Vector3(aReader.ReadSingle(), aReader.ReadSingle(), aReader.ReadSingle());
109 public static void WriteVector4(
this BinaryWriter aWriter, Vector4 aVec)
111 aWriter.Write(aVec.x); aWriter.Write(aVec.y); aWriter.Write(aVec.z); aWriter.Write(aVec.w);
113 public static Vector4 ReadVector4(
this BinaryReader aReader)
115 return new Vector4(aReader.ReadSingle(), aReader.ReadSingle(), aReader.ReadSingle(), aReader.ReadSingle());
118 public static void WriteColor(
this BinaryWriter aWriter,
Color aCol)
120 aWriter.Write(aCol.r); aWriter.Write(aCol.g); aWriter.Write(aCol.b); aWriter.Write(aCol.a);
122 public static Color ReadColor(
this BinaryReader aReader)
124 return new Color(aReader.ReadSingle(), aReader.ReadSingle(), aReader.ReadSingle(), aReader.ReadSingle());
127 static GameObjectData GOtoGOD(GameObject go,
bool recursive =
false)
131 god.Type = go.GetComponent<MeshFilter>() ? (
byte)0 : go.GetComponent<
UnityEngine.
UI.RawImage>() ? (
byte)1 : (byte)255;
132 god.Position = go.transform.position;
133 god.Rotation = go.transform.eulerAngles;
134 god.Scale = go.transform.lossyScale;
139 var mf = go.GetComponent<MeshFilter>();
142 god.MeshData = MeshSerializer.SerializeMesh(mf.mesh);
143 god.MeshLength = god.MeshData.Length;
145 var mr = go.GetComponent<MeshRenderer>();
146 god.MaterialCount = 0;
149 god.MaterialCount = (short)mr.materials.Length;
150 var list =
new List<MatData>();
151 for (
int i = 0; i < mr.materials.Length; i++)
153 var mat = mr.materials[i];
155 if (mat.HasProperty(
"_MainTex"))
157 Texture2D texture2D = duplicateTexture((Texture2D)mat.GetTexture(
"_MainTex"));
159 matData.texture = (texture2D)?.GetRawTextureData();
161 matData.textureFormat = texture2D.format;
162 if (matData.texture !=
null)
164 matData.textureLength = matData.texture.Length;
165 matData.textureSize =
new Vector2(texture2D.width, texture2D.height);
168 if (mat.HasProperty(
"_MetallicGlossMap"))
170 Texture2D texture2D = duplicateTexture((Texture2D)mat.GetTexture(
"_MetallicGlossMap"));
171 matData.metallic = (texture2D)?.GetRawTextureData();
173 matData.metallicFormat = texture2D.format;
174 if (matData.metallic !=
null)
176 matData.metallicLength = matData.metallic.Length;
177 matData.metallicSize =
new Vector2(texture2D.width, texture2D.height);
180 if (mat.HasProperty(
"_BumpMap"))
182 Texture2D texture2D = duplicateTexture((Texture2D)mat.GetTexture(
"_BumpMap"));
183 matData.normal = (texture2D)?.GetRawTextureData();
185 matData.normalFormat = texture2D.format;
186 if (matData.normal !=
null)
188 matData.normalLength = matData.normal.Length;
189 matData.normalSize =
new Vector2(texture2D.width, texture2D.height);
192 if (mat.HasProperty(
"_OcclusionMap"))
194 Texture2D texture2D = duplicateTexture((Texture2D)mat.GetTexture(
"_OcclusionMap"));
195 matData.occlusion = (texture2D)?.GetRawTextureData();
197 matData.occlusionFormat = texture2D.format;
198 if (matData.occlusion !=
null)
200 matData.occlusionLength = matData.occlusion.Length;
201 matData.occlusionSize =
new Vector2(texture2D.width, texture2D.height);
204 if (mat.HasProperty(
"_Metallic"))
205 matData.fMetallic = mat.GetFloat(
"_Metallic");
206 if (mat.HasProperty(
"_Glossiness"))
207 matData.fSmoothness = mat.GetFloat(
"_Glossiness");
208 if (mat.HasProperty(
"_Color"))
209 matData.color = mat.GetColor(
"_Color");
213 god.Materials = list;
220 god.X = ri.texture.width;
221 god.Y = ri.texture.height;
222 god.MeshData = duplicateTexture((Texture2D)ri.texture)?.GetRawTextureData();;
223 god.MeshLength = god.MeshData.Length;
224 god.MaterialCount = 0;
228 god.ChildrenCount = (short)go.transform.childCount;
229 god.Children =
new List<GameObjectData>();
230 if (go.transform.childCount > 0)
232 foreach (Transform child
in go.transform)
234 god.Children.Add(GOtoGOD(child.gameObject,
true));
240 god.ChildrenCount = 0;
241 god.Children =
new List<GameObjectData>();
246 static GameObject GODtoGO(
GameObjectData god, Transform wrapper =
null)
248 var go =
new GameObject();
250 go.transform.SetParent(wrapper,
true);
252 go.transform.position = god.
Position;
253 go.transform.eulerAngles = god.
Rotation;
254 go.transform.localScale = god.
Scale;
257 var mf = go.AddComponent<MeshFilter>();
258 MeshSerializer.DeserializeMesh(god.
MeshData, mf.mesh);
259 var mr = go.AddComponent<MeshRenderer>();
261 for (
int i = 0; i < god.
Materials.Count; i++)
265 if (mr.materials[i].HasProperty(
"_MainTex"))
267 if (matData.texture !=
null && matData.texture.Length > 0)
269 var texture =
new Texture2D((
int)matData.textureSize.x, (
int)matData.textureSize.y, matData.textureFormat,
false);
270 texture.LoadRawTextureData(matData.texture);
272 mr.materials[i].SetTexture(
"_MainTex", texture);
275 if (mr.materials[i].HasProperty(
"_MetallicGlossMap"))
277 if (matData.metallic !=
null && matData.metallic.Length > 0)
279 var texture =
new Texture2D((
int)matData.metallicSize.x, (
int)matData.metallicSize.y, matData.metallicFormat,
false);
280 texture.LoadRawTextureData(matData.metallic);
282 mr.materials[i].SetTexture(
"_MetallicGlossMap", texture);
285 if (mr.materials[i].HasProperty(
"_BumpMap"))
287 if (matData.normal !=
null && matData.normal.Length > 0)
289 var texture =
new Texture2D((
int)matData.normalSize.x, (
int)matData.normalSize.y, matData.normalFormat,
false);
290 texture.LoadRawTextureData(matData.normal);
292 mr.materials[i].SetTexture(
"_BumpMap", texture);
295 if (mr.materials[i].HasProperty(
"_OcclusionMap"))
297 if (matData.occlusion !=
null && matData.occlusion.Length > 0)
299 var texture =
new Texture2D((
int)matData.occlusionSize.x, (
int)matData.occlusionSize.y, matData.occlusionFormat,
false);
300 texture.LoadRawTextureData(matData.occlusion);
302 mr.materials[i].SetTexture(
"_OcclusionMap", texture);
305 if (mr.materials[i].HasProperty(
"_Metallic"))
306 mr.materials[i].SetFloat(
"_Metallic", matData.fMetallic);
307 if (mr.materials[i].HasProperty(
"_Glossiness"))
308 mr.materials[i].SetFloat(
"_Glossiness", matData.fSmoothness);
309 if (mr.materials[i].HasProperty(
"_Color"))
310 mr.materials[i].SetColor(
"_Color", matData.color);
317 var texture =
new Texture2D(god.
X, god.
Y);
318 texture.LoadRawTextureData(god.
MeshData);
320 ri.texture = texture;
321 var canvas = go.AddComponent<Canvas>();
322 canvas.renderMode = RenderMode.WorldSpace;
323 var rt = go.GetComponent<RectTransform>();
328 GODtoGO(c, go.transform);
329 Debug.Log($
"serialized '{go.name}'");
333 public static void WriteGameObject(
this BinaryWriter aWriter, GameObject aGo,
bool recursive =
false)
335 aWriter.WriteGameObjectData(GOtoGOD(aGo, recursive));
337 public static void WriteGameObjectData(
this BinaryWriter aWriter,
GameObjectData aGod)
340 aWriter.Write(aGod.
Name);
341 aWriter.Write(aGod.
Type);
342 aWriter.WriteVector3(aGod.
Position);
343 aWriter.WriteVector3(aGod.
Rotation);
344 aWriter.WriteVector3(aGod.
Scale);
345 aWriter.Write(aGod.
X);
346 aWriter.Write(aGod.
Y);
353 aWriter.WriteMatData(mat);
355 foreach (var child
in aGod.
Children)
356 aWriter.WriteGameObjectData(child);
360 static Texture2D duplicateTexture(Texture2D source)
362 if (source ==
null)
return null;
363 RenderTexture renderTex = RenderTexture.GetTemporary(
367 RenderTextureFormat.Default,
368 RenderTextureReadWrite.Linear);
371 RenderTexture previous = RenderTexture.active;
372 RenderTexture.active = renderTex;
373 Texture2D readableText =
new Texture2D(source.width, source.height);
374 readableText.ReadPixels(
new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
375 readableText.Apply();
376 RenderTexture.active = previous;
377 RenderTexture.ReleaseTemporary(renderTex);
381 public static GameObject ReadGameObject(
this BinaryReader aReader, Transform wrapper =
null)
383 return GODtoGO(aReader.ReadGameObjectData(), wrapper);
385 public static GameObjectData ReadGameObjectData(
this BinaryReader aReader)
388 var name = aReader.ReadString();
389 var type = aReader.ReadByte();
390 var pos = aReader.ReadVector3();
391 var rot = aReader.ReadVector3();
392 var scale = aReader.ReadVector3();
393 var x = aReader.ReadInt32();
394 var y = aReader.ReadInt32();
395 var meshLength = aReader.ReadInt32();
396 var mesh = aReader.ReadBytes(meshLength);
397 var materialCount = aReader.ReadInt16();
398 var matList =
new List<MatData>();
399 for (
int i = 0; i < materialCount; i++)
400 matList.Add(aReader.ReadMatData());
401 var childrenCount = aReader.ReadInt16();
402 var childList =
new List<GameObjectData>();
403 for (
int i = 0; (i < childrenCount); i++)
404 childList.Add(aReader.ReadGameObjectData());
417 MeshLength = meshLength,
419 MaterialCount = materialCount,
421 ChildrenCount = childrenCount,
425 public static void WriteMatData(
this BinaryWriter aWriter,
MatData aMat)
441 aWriter.Write(aMat.
normal);
449 aWriter.WriteColor(aMat.
color);
451 public static MatData ReadMatData(
this BinaryReader aReader)
453 var tL = aReader.ReadInt32();
454 var tS = aReader.ReadVector2();
455 var tF = (TextureFormat)aReader.ReadInt32();
456 var t = aReader.ReadBytes(tL);
457 var mL = aReader.ReadInt32();
458 var mS = aReader.ReadVector2();
459 var mF = (TextureFormat)aReader.ReadInt32();
460 var m = aReader.ReadBytes(mL);
461 var nL = aReader.ReadInt32();
462 var nS = aReader.ReadVector2();
463 var nF = (TextureFormat)aReader.ReadInt32();
464 var n = aReader.ReadBytes(nL);
465 var oL = aReader.ReadInt32();
466 var oS = aReader.ReadVector2();
467 var oF = (TextureFormat)aReader.ReadInt32();
468 var o = aReader.ReadBytes(oL);
469 var mf = aReader.ReadSingle();
470 var sf = aReader.ReadSingle();
471 var c = aReader.ReadColor();
487 occlusionLength = oL,
489 occlusionFormat = oF,
498 public static void WriteMatrix4x4(
this BinaryWriter aWriter, Matrix4x4 aMat)
500 aWriter.Write(aMat.m00); aWriter.Write(aMat.m01); aWriter.Write(aMat.m02); aWriter.Write(aMat.m03);
501 aWriter.Write(aMat.m10); aWriter.Write(aMat.m11); aWriter.Write(aMat.m12); aWriter.Write(aMat.m13);
502 aWriter.Write(aMat.m20); aWriter.Write(aMat.m21); aWriter.Write(aMat.m22); aWriter.Write(aMat.m23);
503 aWriter.Write(aMat.m30); aWriter.Write(aMat.m31); aWriter.Write(aMat.m32); aWriter.Write(aMat.m33);
505 public static Matrix4x4 ReadMatrix4x4(
this BinaryReader aReader)
507 var m =
new Matrix4x4();
508 m.m00 = aReader.ReadSingle(); m.m01 = aReader.ReadSingle(); m.m02 = aReader.ReadSingle(); m.m03 = aReader.ReadSingle();
509 m.m10 = aReader.ReadSingle(); m.m11 = aReader.ReadSingle(); m.m12 = aReader.ReadSingle(); m.m13 = aReader.ReadSingle();
510 m.m20 = aReader.ReadSingle(); m.m21 = aReader.ReadSingle(); m.m22 = aReader.ReadSingle(); m.m23 = aReader.ReadSingle();
511 m.m30 = aReader.ReadSingle(); m.m31 = aReader.ReadSingle(); m.m32 = aReader.ReadSingle(); m.m33 = aReader.ReadSingle();
515 public static void WriteBoneWeight(
this BinaryWriter aWriter, BoneWeight aWeight)
517 aWriter.Write(aWeight.boneIndex0); aWriter.Write(aWeight.weight0);
518 aWriter.Write(aWeight.boneIndex1); aWriter.Write(aWeight.weight1);
519 aWriter.Write(aWeight.boneIndex2); aWriter.Write(aWeight.weight2);
520 aWriter.Write(aWeight.boneIndex3); aWriter.Write(aWeight.weight3);
522 public static BoneWeight ReadBoneWeight(
this BinaryReader aReader)
524 var w =
new BoneWeight();
525 w.boneIndex0 = aReader.ReadInt32(); w.weight0 = aReader.ReadSingle();
526 w.boneIndex1 = aReader.ReadInt32(); w.weight1 = aReader.ReadSingle();
527 w.boneIndex2 = aReader.ReadInt32(); w.weight2 = aReader.ReadSingle();
528 w.boneIndex3 = aReader.ReadInt32(); w.weight3 = aReader.ReadSingle();
List< MatData > Materials
List< GameObjectData > Children
TextureFormat textureFormat
TextureFormat normalFormat
TextureFormat occlusionFormat
TextureFormat metallicFormat