Search Unity

Resolved NullReferenceException during Deserialization at "GameObjectSceneRefCount" error?

Discussion in 'Entity Component System' started by Zerio777, Jul 6, 2021.

  1. Zerio777

    Zerio777

    Joined:
    Jan 12, 2015
    Posts:
    24
    Trying to Deserialize into an empty World, but I'm getting an error that references Scene bits. Does anybody know needs to be done to instantiate the needed object reference, or to get past this error to DeserializeWorld using the SerializeUtility?

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. Unity.Scenes.GameObjectSceneRefCount.Retain () (at Library/PackageCache/com.unity.entities@0.17.0-preview.42/Unity.Scenes/GameObjectSceneManager.cs:106)
    3. Unity.Scenes.GameObjectSceneData.Retain () (at Library/PackageCache/com.unity.entities@0.17.0-preview.42/Unity.Scenes/GameObjectSceneComponents.cs:30)
    4. Unity.Entities.ManagedComponentStore.InsertSharedComponentAssumeNonDefault (System.Int32 typeIndex, System.Int32 hashCode, System.Object newData) (at Library/PackageCache/com.unity.entities@0.17.0-preview.41/Unity.Entities/ManagedComponentStore.cs:222)
    5. Unity.Entities.Serialization.SerializeUtility.ReadSharedComponents (Unity.Entities.ExclusiveEntityTransaction manager, Unity.Entities.Serialization.ManagedObjectBinaryReader managedDataReader, Unity.Collections.NativeArray`1[T] sharedComponentRemap, Unity.Collections.NativeArray`1[T] sharedComponentRecordArray) (at Library/PackageCache/com.unity.entities@0.17.0-preview.41/Unity.Entities/Serialization/SerializeUtility.cs:857)
    6. Unity.Entities.Serialization.SerializeUtility.DeserializeWorld (Unity.Entities.ExclusiveEntityTransaction manager, Unity.Entities.Serialization.BinaryReader reader, System.Object[] unityObjects) (at Library/PackageCache/com.unity.entities@0.17.0-preview.41/Unity.Entities/Serialization/SerializeUtility.cs:212)
    "m_RefCount++" is where the null is called out, and I'm just stumped.
     
  2. Zerio777

    Zerio777

    Joined:
    Jan 12, 2015
    Posts:
    24
    Yeah, so just this basic few lines, even in a blank project, gives me null error at "GameObjectSceneRefCount.Retain++"

    Code (CSharp):
    1. static ReferencedUnityObjects test;
    2. public static void SaveGame() {
    3.     EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
    4.     using ( var writer = new StreamBinaryWriter(Application.persistentDataPath + " /Bob") ) {
    5.         SerializeUtility.SerializeWorld(entityManager, writer, out object[] obj);
    6.         SerializeUtilityHybrid.SerializeObjectReferences((Object[]) obj, out test);
    7.     }
    8. }
    9.  
    10. public static void LoadGame() {
    11.     World localWorld = new World("local world");
    12.     var transaction = localWorld.EntityManager.BeginExclusiveEntityTransaction();
    13.     using ( var reader = new StreamBinaryReader(Application.persistentDataPath + "/Bob") ) {
    14.         SerializeUtilityHybrid.DeserializeObjectReferences(test, out Object[] obj);
    15.         SerializeUtility.DeserializeWorld(transaction, reader, obj);
    16. // WHERE MY NULL ERROR OCCURS
    17.     }
    18.     localWorld.EntityManager.EndExclusiveEntityTransaction();
    19.     World.DefaultGameObjectInjectionWorld.EntityManager.MoveEntitiesFrom(localWorld.EntityManager);
    20. }
     
  3. Zerio777

    Zerio777

    Joined:
    Jan 12, 2015
    Posts:
    24
    Does not, at least simply, serialize DefaultGameObjectInjectionWorld. Copying entities into a new "Save World" seems to be working in implementation so far.
     
  4. Zerio777

    Zerio777

    Joined:
    Jan 12, 2015
    Posts:
    24
    Solved: Must remove scene entity from serialization query (I did by creating a SaveWorld I copy everything to w/ a translation (for now)), and then it deserializes without issue (instant).

    Now, just to figure out how to get this ReferencedUnityObjects down.

    Code (CSharp):
    1. var testworld = new World("SaveWorld");
    2. using NativeArray<Entity> entities_to_save = World.DefaultGameObjectInjectionWorld.EntityManager.CreateEntityQuery(new ComponentType[]{typeof(Translation)}).ToEntityArray(Allocator.Temp);
    3. testworld.EntityManager.CopyEntitiesFrom(World.DefaultGameObjectInjectionWorld.EntityManager, entities_to_save);
     
    Last edited: Jul 8, 2021
  5. Zerio777

    Zerio777

    Joined:
    Jan 12, 2015
    Posts:
    24
    Okay. It's easier than I made it. If anyone stumbles in here needing same help, here you are:
    Code (CSharp):
    1.  
    2. public class SystemManager : MonoBehaviour {
    3.     static EntityQuery eq;
    4.     void Start() => eq = World.DefaultGameObjectInjectionWorld.EntityManager.CreateEntityQuery(
    5.         new EntityQueryDesc { Any = new ComponentType[] { typeof(Save_Tag) } });
    6.  
    7.     public static void Save_Game() {
    8.         var url = Application.persistentDataPath;
    9.         object[] obj;
    10.         var meshes = Resources.LoadAll<Mesh>("");
    11.         var mats = Resources.LoadAll<Material>("");
    12.  
    13.         using World saveWorld = new World("SaveWorld");
    14.         using NativeArray<Entity> entities_to_save = eq.ToEntityArray(Allocator.Temp);
    15.         saveWorld.EntityManager.CopyEntitiesFrom(World.DefaultGameObjectInjectionWorld.EntityManager, entities_to_save);
    16.  
    17.         using ( BinaryWriter writer = new StreamBinaryWriter(url + "/help") )
    18.             SerializeUtility.SerializeWorld(saveWorld.EntityManager, writer, out obj);
    19.         Debug.Log("Saving : [" + obj.Length + "] (" + Application.persistentDataPath + ")");
    20.  
    21.         using ( BinaryWriter writer = new StreamBinaryWriter(url + "/hurt") ) {
    22.             writer.Write(obj.Length);
    23.             for ( int i = 0 ; i < obj.Length ; i++ ) {
    24.                 bool typeMesh = obj[i].GetType() == typeof(Mesh);
    25.                 for ( int j = 0 ; j < (typeMesh ? meshes.Length : mats.Length) ; j++ )
    26.                     if ( obj[i].Equals((typeMesh ? (Object) meshes[j] : mats[j])) )
    27.                         writer.Write(j * 10 + (typeMesh ? 0 : 1));
    28.             }
    29.         }
    30.     }
    31.  
    32.     public static void Load_Game() {
    33.         string url = Application.persistentDataPath;
    34.         Object[] obj;
    35.         var meshes = Resources.LoadAll<Mesh>("");
    36.         var mats = Resources.LoadAll<Material>("");
    37.  
    38.         using ( BinaryReader reader = new StreamBinaryReader(url + "/hurt") ) {
    39.             obj = new Object[reader.ReadInt()];
    40.             Debug.Log("Loading : [" + obj.Length + "] (" + url + ")");
    41.             for ( int i = 0 ; i < obj.Length ; i++ ) {
    42.                 int id = reader.ReadInt();
    43.                 obj[i] = id % 2 == 0 ? (Object) meshes[id / 10] : mats[id / 10];
    44.             }
    45.         }
    46.  
    47.         using World loadWorld = new World("LoadWorld");
    48.         var entityTransaction = loadWorld.EntityManager.BeginExclusiveEntityTransaction();
    49.         using ( BinaryReader reader = new StreamBinaryReader(url + "/help") )
    50.             SerializeUtility.DeserializeWorld(entityTransaction, reader, obj);
    51.         loadWorld.EntityManager.EndExclusiveEntityTransaction();
    52.  
    53.         World.DefaultGameObjectInjectionWorld.EntityManager.DestroyEntity(eq);
    54.         World.DefaultGameObjectInjectionWorld.EntityManager.MoveEntitiesFrom(loadWorld.EntityManager);
    55.     }
    56. }
     
    ITR, DUremovich and makkara like this.
  6. DUremovich

    DUremovich

    Joined:
    Oct 17, 2018
    Posts:
    1
    You're a gentleman and a scholar! This didn't entirely work for me, but it's gotten me close enough that I can make it work.

    For some reason for me when it gets to this block in Load_game
    Code (CSharp):
    1. for ( int i = 0 ; i < obj.Length ; i++ ) {
    2.                 int id = reader.ReadInt();
    3.                 obj[i] = id % 2 == 0 ? (Object) meshes[id / 10] : mats[id / 10];
    4.             }
    the editor freezes entirely for me. I suspect the reader.ReadInt() is trying to read a line that isn't there and having a heart attack but I'm not sure why.