c# - Serialized nested list corrupt at editor reboot (Unity3D) -
i trying serialize scriptable object contains dictionary plan use build levels game. after object created , initialized, save asset attached monobehavior generates level dynamically. since unity can't serialize dictionaries using lists in conjunction iserializationcallbackreceiver interface, save , load data contained in dictionary. scriptable object code
public class levelsdatabase : scriptableobject, iserializationcallbackreceiver { public dictionary<roombiome, dictionary<roomtype, levelinfolistwrapper>> biomedictionaries = new dictionary<roombiome, dictionary<roomtype, levelinfolistwrapper>>(); // serialization variables [serializefield] private list<roombiome> _biomedictionarieskeys = new list<roombiome>(); [serializefield] private list<roomtype> _levelinfolistkeys = new list<roomtype>(); [serializefield] private list<levelinfolistwrapper> _levelinfolistvalues = new list<levelinfolistwrapper>(); public void generatelevelsdatabase() { debug.log("generated database"); loadlevelinfo(); } // database generation code public void onbeforeserialize() { try { _biomedictionarieskeys.clear(); _levelinfolistkeys.clear(); _levelinfolistvalues.clear(); foreach (var biomedictionary in biomedictionaries) { _biomedictionarieskeys.add(biomedictionary.key); } var key = _biomedictionarieskeys[0]; foreach (var roomtypedictionary in biomedictionaries[key]) { _levelinfolistkeys.add(roomtypedictionary.key); } foreach (var biomekey in _biomedictionarieskeys) { foreach (var roomtypekey in _levelinfolistkeys) { var biomedictionary = biomedictionaries[biomekey]; if (!biomedictionary.containskey(roomtypekey)) { continue; } var levelinfolist = biomedictionaries[biomekey][roomtypekey]; _levelinfolistvalues.add(levelinfolist); } } } catch (exception e) { debug.log("something horrible happened"); } } public void onafterdeserialize() { biomedictionaries.clear(); int index = 0; foreach (var biomekey in _biomedictionarieskeys) { biomedictionaries.add(biomekey, new dictionary<roomtype, levelinfolistwrapper>()); foreach (var roomtype in _levelinfolistkeys) { if (index >= _levelinfolistvalues.count) { break; } // todo quick fix, replace when refactoring if (roomtype != _levelinfolistvalues[index].levelinfolist[0].roomtype) { continue; } biomedictionaries[biomekey].add(roomtype, _levelinfolistvalues[index]); index ++; } } debug.log("deserialized"); }
roombiome , roomtype enums , levelinfolistwrapper wrapper list of levelinfo objects defined following:
[serializable] public class levelinfolistwrapper { public list<levelinfo> levelinfolist = new list<levelinfo>(); }
levelinfo scriptable object contains data belonging rooms used in level. defined
[serializable] public class levelinfo : scriptableobject { public roomtype roomtype; public roombiome roombiome; public levelsenum level; [serializefield] private list<entrypoint> _levelentrypoints = new list<entrypoint>(); //todo add breakable spawners , combat triggers info public void addentrypoints(ilist<entrypoint> entrypoints) { _levelentrypoints.addrange(entrypoints); } public list<entrypoint> getentrypoints() { return _levelentrypoints; } }
levelinfo has, among data list of entrypoints defined such:
[serializable] public class entrypoint { public string tolevel; public roombiome tobiome; public vector3 position; public int index; public entrypointposition positioninroom; }
this code works , serialization/deserialization process handled correctly when play , stop editor. unfortunately if quit editor , restart it, lists list < levelinfo > contained in _levelinfolistvalues not correctly deserialized , contain levelinfo references initialized default constructor. have read few posts , references running out of ideas on how make unity serialize correctly list of levelinfowrapper. idea ditch unity's serialization , use somenthing xml or json tempting before resorting wondering if has suggestion possible solution. thanks!
Comments
Post a Comment