public static void Deserialize(EntityManager manager, BinaryReader reader, ReferencedUnityObjects objRefs) { DeserializeObjectReferences(objRefs, out var objectReferences); var transaction = manager.BeginExclusiveEntityTransaction(); SerializeUtility.DeserializeWorld(transaction, reader, objectReferences); manager.EndExclusiveEntityTransaction(); }
void ScheduleSceneRead(ReferencedUnityObjects objRefs) { var transaction = _EntityManager.BeginExclusiveEntityTransaction(); SerializeUtilityHybrid.DeserializeObjectReferences(objRefs, out var objectReferences); var loadJob = new AsyncLoadSceneJob { Transaction = transaction, LoadingOperationHandle = GCHandle.Alloc(this), ObjectReferencesHandle = GCHandle.Alloc(objectReferences), FileContent = _FileContent }; _EntityManager.ExclusiveEntityTransactionDependency = loadJob.Schedule(JobHandle.CombineDependencies(_EntityManager.ExclusiveEntityTransactionDependency, _ReadHandle.JobHandle)); }
public static void DeserializeObjectReferences(ReferencedUnityObjects objRefs, out UnityEngine.Object[] objectReferences) { if (objRefs == null) { objectReferences = null; return; } objectReferences = new UnityEngine.Object[objRefs.Array.Length]; // NOTE: Object references must not include fake object references, they must be real null. // The Unity.Properties deserializer can't handle them correctly. // We might want to add support for handling fake null, // but it would require tight integration in the deserialize function so that a correct fake null unityengine.object can be constructed on deserialize for (int i = 0; i != objRefs.Array.Length; i++) { if (objRefs.Array[i] != null) { objectReferences[i] = objRefs.Array[i]; } } // Companion Objects // When using bundles, the Companion GameObjects cannot be directly used (prefabs), so we need to instantiate everything. #if !UNITY_EDITOR var sourceToInstance = new Dictionary <UnityEngine.GameObject, UnityEngine.GameObject>(); foreach (var companionIndex in objRefs.CompanionObjectIndices) { var source = objectReferences[companionIndex] as UnityEngine.GameObject; var instance = UnityEngine.Object.Instantiate(source); objectReferences[companionIndex] = instance; sourceToInstance.Add(source, instance); } for (int i = 0; i != objectReferences.Length; i++) { if (objectReferences[i] is UnityEngine.Component component) { objectReferences[i] = sourceToInstance[component.gameObject].GetComponent(component.GetType()); } } #endif }
private void UpdateBlocking() { if (_LoadingStatus == LoadingStatus.Completed) { return; } if (_SceneSize == 0) { return; } try { _StartTime = Time.realtimeSinceStartup; _FileContent = (byte *)UnsafeUtility.Malloc(_SceneSize, 16, Allocator.Persistent); ReadCommand cmd; cmd.Buffer = _FileContent; cmd.Offset = 0; cmd.Size = _SceneSize; _ReadHandle = AsyncReadManager.Read(_ScenePath, &cmd, 1); if (_ExpectedObjectReferenceCount != 0) { #if UNITY_EDITOR var resourceRequests = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(_ResourcesPathObjRefs); _ResourceObjRefs = (ReferencedUnityObjects)resourceRequests[0]; #else _SceneBundleHandle = SceneBundleHandle.CreateOrRetainBundle(_ResourcesPathObjRefs); _ResourceObjRefs = _SceneBundleHandle.AssetBundle.LoadAsset <ReferencedUnityObjects>(Path.GetFileName(_ResourcesPathObjRefs)); #endif } ScheduleSceneRead(_ResourceObjRefs); _EntityManager.ExclusiveEntityTransactionDependency.Complete(); } catch (Exception e) { _LoadingFailure = e.Message; } _LoadingStatus = LoadingStatus.Completed; }
public AsyncLoadSceneOperation(AsyncLoadSceneData asyncLoadSceneData, bool usingLiveLink) { _Data = asyncLoadSceneData; _LoadingStatus = LoadingStatus.NotStarted; if (usingLiveLink && _ExpectedObjectReferenceCount != 0) { // Resolving must happen on the main thread using (var data = new NativeArray <byte>(File.ReadAllBytes(_ResourcesPathObjRefs), Allocator.Temp)) using (var reader = new MemoryBinaryReader((byte *)data.GetUnsafePtr())) { var numObjRefGUIDs = reader.ReadInt(); NativeArray <RuntimeGlobalObjectId> objRefGUIDs = new NativeArray <RuntimeGlobalObjectId>(numObjRefGUIDs, Allocator.Temp); reader.ReadArray(objRefGUIDs, numObjRefGUIDs); var objs = new UnityEngine.Object[numObjRefGUIDs]; LiveLinkPlayerAssetRefreshSystem._GlobalAssetObjectResolver.ResolveObjects(objRefGUIDs, objs); objRefGUIDs.Dispose(); _ResourceObjRefs = ScriptableObject.CreateInstance <ReferencedUnityObjects>(); _ResourceObjRefs.Array = objs; } } }
private void UpdateAsync() { //@TODO: Try to overlap Resources load and entities scene load // Begin Async resource load if (_LoadingStatus == LoadingStatus.NotStarted) { if (_SceneSize == 0) { return; } try { _StartTime = Time.realtimeSinceStartup; _FileContent = (byte *)UnsafeUtility.Malloc(_SceneSize, 16, Allocator.Persistent); ReadCommand cmd; cmd.Buffer = _FileContent; cmd.Offset = 0; cmd.Size = _SceneSize; _ReadHandle = AsyncReadManager.Read(_ScenePath, &cmd, 1); if (_ExpectedObjectReferenceCount != 0) { #if UNITY_EDITOR var resourceRequests = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(_ResourcesPathObjRefs); _ResourceObjRefs = (ReferencedUnityObjects)resourceRequests[0]; _LoadingStatus = LoadingStatus.WaitingForResourcesLoad; #else _SceneBundleHandle = SceneBundleHandle.CreateOrRetainBundle(_ResourcesPathObjRefs); _LoadingStatus = LoadingStatus.WaitingForAssetBundleLoad; #endif } else { _LoadingStatus = LoadingStatus.WaitingForEntitiesLoad; } } catch (Exception e) { _LoadingFailure = e.Message; _LoadingStatus = LoadingStatus.Completed; } } // Once async asset bundle load is done, we can read the asset if (_LoadingStatus == LoadingStatus.WaitingForAssetBundleLoad) { if (!_SceneBundleHandle.IsReady()) { return; } if (!_SceneBundleHandle.AssetBundle) { _LoadingFailure = $"Failed to load Asset Bundle '{_ResourcesPathObjRefs}'"; _LoadingStatus = LoadingStatus.Completed; return; } var fileName = Path.GetFileName(_ResourcesPathObjRefs); _AssetRequest = _SceneBundleHandle.AssetBundle.LoadAssetAsync(fileName); _LoadingStatus = LoadingStatus.WaitingForAssetLoad; } // Once async asset bundle load is done, we can read the asset if (_LoadingStatus == LoadingStatus.WaitingForAssetLoad) { if (!_AssetRequest.isDone) { return; } if (!_AssetRequest.asset) { _LoadingFailure = $"Failed to load Asset '{Path.GetFileName(_ResourcesPathObjRefs)}'"; _LoadingStatus = LoadingStatus.Completed; return; } _ResourceObjRefs = _AssetRequest.asset as ReferencedUnityObjects; if (_ResourceObjRefs == null) { _LoadingFailure = $"Failed to load object references resource '{_ResourcesPathObjRefs}'"; _LoadingStatus = LoadingStatus.Completed; return; } _LoadingStatus = LoadingStatus.WaitingForEntitiesLoad; } // Once async resource load is done, we can async read the entity scene data if (_LoadingStatus == LoadingStatus.WaitingForResourcesLoad) { if (_ResourceObjRefs == null) { _LoadingFailure = $"Failed to load object references resource '{_ResourcesPathObjRefs}'"; _LoadingStatus = LoadingStatus.Completed; return; } _LoadingStatus = LoadingStatus.WaitingForEntitiesLoad; } if (_LoadingStatus == LoadingStatus.WaitingForEntitiesLoad) { try { _LoadingStatus = LoadingStatus.WaitingForSceneDeserialization; ScheduleSceneRead(_ResourceObjRefs); if (_BlockUntilFullyLoaded) { _EntityManager.ExclusiveEntityTransactionDependency.Complete(); } } catch (Exception e) { _LoadingFailure = e.Message; _LoadingStatus = LoadingStatus.Completed; } } // Complete Loading status if (_LoadingStatus == LoadingStatus.WaitingForSceneDeserialization) { if (_EntityManager.ExclusiveEntityTransactionDependency.IsCompleted) { _EntityManager.ExclusiveEntityTransactionDependency.Complete(); _LoadingStatus = LoadingStatus.Completed; var currentTime = Time.realtimeSinceStartup; var totalTime = currentTime - _StartTime; System.Console.WriteLine($"Streamed scene with {totalTime * 1000,3:f0}ms latency from {_ScenePath}"); } } }
public static void SerializeObjectReferences(UnityEngine.Object[] referencedObjects, out ReferencedUnityObjects objRefs) { objRefs = null; if (referencedObjects?.Length > 0) { objRefs = UnityEngine.ScriptableObject.CreateInstance <ReferencedUnityObjects>(); objRefs.Array = referencedObjects; } }
public static void Serialize(EntityManager manager, BinaryWriter writer, out ReferencedUnityObjects objRefs, NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapInfos) { SerializeUtility.SerializeWorld(manager, writer, out var referencedObjects, entityRemapInfos); SerializeObjectReferences((UnityEngine.Object[])referencedObjects, out objRefs); }