Last active
November 12, 2022 20:53
-
-
Save andrew-raphael-lukasik/66d898be737734f26e607e6526d22901 to your computer and use it in GitHub Desktop.
(dots) code for world serialization and deserialization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src: https://gist.github.com/andrew-raphael-lukasik/66d898be737734f26e607e6526d22901 | |
using IO = System.IO; | |
using UnityEngine; | |
using Unity.Entities; | |
using Unity.Scenes; | |
using Unity.Entities.Serialization; | |
public static class Worlds | |
{ | |
public static World Create ( string name , WorldSystemFilterFlags filterFlags = WorldSystemFilterFlags.Default , params System.Type[] otherSystems ) | |
{ | |
var world = new World( name ); | |
var systems = DefaultWorldInitialization.GetAllSystems( filterFlags ); | |
DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups( world , systems ); | |
if( otherSystems!=null && otherSystems.Length!=0 ) | |
DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups( world , otherSystems ); | |
ScriptBehaviourUpdateOrder.AddWorldToCurrentPlayerLoop( world ); | |
return world; | |
} | |
// Assumes you store Mesh assets in ../Resources/Meshes/ folder | |
// Assumes you store Materials assets in ../Resources/Materials/ folder | |
public static void Serialize ( World world , string absoluteFilePath ) | |
{ | |
var parentDirectoryPath = IO.Path.GetDirectoryName(absoluteFilePath); | |
if( !IO.File.Exists(parentDirectoryPath) ) IO.Directory.CreateDirectory(parentDirectoryPath); | |
var entityManager = world.EntityManager; | |
using( BinaryWriter writer = new StreamBinaryWriter(absoluteFilePath) ) | |
{ | |
// write binary file: | |
SerializeUtilityHybrid.Serialize( entityManager , writer , out var objRefs ); | |
Debug.Log($"\t\t\tbinary file saved: \'{absoluteFilePath}\'"); | |
// write managed data (text) file: | |
string managedDataFilePath = IO.Path.ChangeExtension(absoluteFilePath,".managed_data"); | |
if( objRefs!=null ) | |
{ | |
var output = new System.Text.StringBuilder(); | |
foreach( var obj in objRefs.Array ) | |
output.AppendLine( $"{obj.name}{k_managed_data_separator}{obj.GetType().FullName}" ); | |
IO.File.WriteAllText( path:managedDataFilePath , contents:output.ToString() ); | |
Object.DestroyImmediate( objRefs ); | |
Debug.Log($"\t\t\tmanaged data file saved: \'{managedDataFilePath}\'"); | |
} | |
else if( IO.File.Exists(managedDataFilePath) ) | |
{ | |
IO.File.Delete(managedDataFilePath); | |
} | |
} | |
} | |
// Assumes you store Mesh assets in ../Resources/Meshes/ folder | |
// Assumes you store Materials assets in ../Resources/Materials/ folder | |
public static void Deserialize ( string absoluteFilePath , World world ) | |
{ | |
string directory = IO.Path.GetDirectoryName( absoluteFilePath ); | |
if( !IO.Directory.Exists(directory) ) | |
{ | |
Debug.LogError($"directory does not exists: \'{directory}\'"); | |
return; | |
} | |
var objRefs = ScriptableObject.CreateInstance<ReferencedUnityObjects>(); | |
objRefs.Array = new Object[0]; | |
{ | |
string managedDataFilePath = IO.Path.ChangeExtension(absoluteFilePath,".managed_data"); | |
Debug.Log($"\treading file: '{managedDataFilePath}'"); | |
string[] lines = IO.File.ReadAllLines( managedDataFilePath ); | |
for( int lineIndex=0 ; lineIndex<lines.Length ; lineIndex++ ) | |
{ | |
string line = lines[lineIndex]; | |
if( line.Length!=0 ) | |
{ | |
string[] nt = line.Split(k_managed_data_separator); | |
string obj_name = nt[0]; | |
string obj_type = nt[1]; | |
Object obj; | |
if( obj_type==typeof(Mesh).FullName ) | |
{ | |
string path = $"Meshes/{obj_name}"; | |
obj = Resources.Load<Mesh>(path); | |
if( obj==null ) Debug.LogWarning($"null when reading resource path: '{path}'"); | |
} | |
else if( obj_type==typeof(Material).FullName ) | |
{ | |
string path = $"Materials/{obj_name}"; | |
obj = Resources.Load<Material>(path); | |
if( obj==null ) Debug.LogWarning($"null when reading resource path: '{path}'"); | |
} | |
else | |
{ | |
Debug.LogError($"'{obj_type}' is unrecognised type"); | |
continue; | |
} | |
System.Array.Resize( ref objRefs.Array , objRefs.Array.Length+1 ); | |
objRefs.Array[ objRefs.Array.Length-1 ] = obj; | |
} | |
} | |
} | |
if( objRefs==null ) | |
{ | |
Debug.LogError($"{nameof(objRefs)} is NULL"); | |
throw new System.Exception(); | |
} | |
var entityManager = world.EntityManager; | |
using( BinaryReader reader = new StreamBinaryReader(absoluteFilePath) ) | |
SerializeUtilityHybrid.Deserialize( entityManager , reader , objRefs ); | |
entityManager.EndExclusiveEntityTransaction(); | |
} | |
const char k_managed_data_separator = '\t'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment