コード例 #1
0
ファイル: SubScene.cs プロジェクト: msfredb7/DMN-ECSTests
        void OnValidate()
        {
            _SceneGUID = new GUID(AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(_SceneAsset)));

            if (_IsAddedToListOfAllSubScenes && IsInMainStage())
            {
                if (_SceneGUID != _AddedSceneGUID)
                {
                    RemoveSceneEntities();
                    if (_SceneGUID != default)
                    {
                        AddSceneEntities();
                    }
                }
            }

            // Validate SubScene build configuration exists
            foreach (var world in World.AllWorlds)
            {
                var sceneSystem = world.GetExistingSystem <SceneSystem>();
                if (sceneSystem is null)
                {
                    continue;
                }

                EntityScenesPaths.CreateBuildConfigurationSceneFile(_SceneGUID, sceneSystem.BuildConfigurationGUID);
            }
        }
 static void CreatePlayerLiveLinkCacheDir()
 {
     if (!Directory.Exists(EntityScenesPaths.GetLiveLinkCacheDirPath()))
     {
         Directory.CreateDirectory(EntityScenesPaths.GetLiveLinkCacheDirPath());
     }
 }
コード例 #3
0
        void ResolveScene(Entity sceneEntity, ref SceneReference scene, RequestSceneLoaded requestSceneLoaded, Hash128 artifactHash)
        {
            // Resolve first (Even if the file doesn't exist we want to stop continously trying to load the section)
            EntityManager.AddBuffer <ResolvedSectionEntity>(sceneEntity);
            EntityManager.AddComponentData(sceneEntity, new ResolvedSceneHash {
                ArtifactHash = artifactHash
            });

            var sceneHeaderPath = EntityScenesPaths.GetLiveLinkCachePath(artifactHash, EntityScenesPaths.PathType.EntitiesHeader, -1);

            if (!File.Exists(sceneHeaderPath))
            {
                Debug.LogError($"Loading Entity Scene failed because the entity header file could not be found: {scene.SceneGUID}\n{sceneHeaderPath}");
                return;
            }

            if (!BlobAssetReference <SceneMetaData> .TryRead(sceneHeaderPath, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out var sceneMetaDataRef))
            {
                Debug.LogError("Loading Entity Scene failed because the entity header file was an old version: " + scene.SceneGUID);
                return;
            }

            LogResolving("ResolveScene (success)", scene.SceneGUID);

            ref var sceneMetaData = ref sceneMetaDataRef.Value;
コード例 #4
0
        internal static List <SceneBundleHandle> LoadSceneBundles(string mainBundlePath, NativeArray <Entities.Hash128> sharedBundles, bool blocking)
        {
            var bundles = new List <SceneBundleHandle>();

            if (sharedBundles.IsCreated)
            {
                for (int i = 0; i < sharedBundles.Length; i++)
                {
                    var path = $"{Application.streamingAssetsPath}/{EntityScenesPaths.RelativePathFolderFor(sharedBundles[i], EntityScenesPaths.PathType.EntitiesSharedReferencesBundle, -1)}";
                    bundles.Add(CreateOrRetainBundle(path));
                }
                sharedBundles.Dispose();
            }

            if (!string.IsNullOrEmpty(mainBundlePath))
            {
                bundles.Insert(0, CreateOrRetainBundle(mainBundlePath));
            }

            if (blocking)
            {
                foreach (var b in bundles)
                {
                    var forceLoad = b.AssetBundle;
                    if (forceLoad == null)
                    {
                        Debug.LogWarning($"Failed to load asset bundle at path {b._bundlePath}");
                    }
                }
            }
            return(bundles);
        }
コード例 #5
0
        unsafe void ReceiveAssetTargetHash(MessageEventArgs args)
        {
            using (var resolvedAssets = args.ReceiveArray <ResolvedAssetID>())
            {
                foreach (var asset in resolvedAssets)
                {
                    if (!asset.TargetHash.IsValid)
                    {
                        // If hash is invalid, then it means we should be waiting on it, but the hash will come later when it finishes importing on the editor
                        LiveLinkMsg.LogReceived($"ReceiveAssetTargetHash => {asset.GUID} | {asset.TargetHash}, Invalid Hash (Still waiting)");
                        m_WaitingForAssets[asset.GUID] = new Hash128();
                    }
                    else
                    {
                        //TODO: Should we compare against already loaded assets here?
                        if (File.Exists(EntityScenesPaths.GetCachePath(asset.TargetHash)))
                        {
                            LiveLinkMsg.LogReceived($"ReceiveAssetTargetHash => {asset.GUID} | {asset.TargetHash}, File.Exists => 'True'");
                            m_WaitingForAssets[asset.GUID] = asset.TargetHash;
                        }
                        else
                        {
                            LiveLinkMsg.LogReceived($"ReceiveAssetTargetHash => {asset.GUID} | {asset.TargetHash}, File.Exists => 'False'");
                            m_WaitingForAssets[asset.GUID] = new Hash128();

                            LiveLinkMsg.LogSend($"AssetBundleBuild request '{asset.GUID}'");
                            m_Connection.Send(LiveLinkMsg.PlayerRequestAssetForGUID, asset.GUID);
                        }
                    }
                }
            }
        }
        void ResolveScene(Entity sceneEntity, ref SceneReference scene, RequestSceneLoaded requestSceneLoaded, Hash128 artifactHash)
        {
            // Resolve first (Even if the file doesn't exist we want to stop continously trying to load the section)
            EntityManager.AddBuffer <ResolvedSectionEntity>(sceneEntity);

#if UNITY_EDITOR && !USE_SUBSCENE_EDITORBUNDLES
            EntityManager.AddComponentData(sceneEntity, new ResolvedSceneHash {
                ArtifactHash = artifactHash
            });

            UnityEditor.Experimental.AssetDatabaseExperimental.GetArtifactPaths(artifactHash, out var paths);

            var sceneHeaderPath = EntityScenesPaths.GetLoadPathFromArtifactPaths(paths, EntityScenesPaths.PathType.EntitiesHeader);
#else
            var sceneHeaderPath = EntityScenesPaths.GetLoadPath(scene.SceneGUID, EntityScenesPaths.PathType.EntitiesHeader, -1);
#endif
            if (!File.Exists(sceneHeaderPath))
            {
                Debug.LogError($"Loading Entity Scene failed because the entity header file could not be found: {scene.SceneGUID}\n{sceneHeaderPath}");
                return;
            }

            if (!BlobAssetReference <SceneMetaData> .TryRead(sceneHeaderPath, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out var sceneMetaDataRef))
            {
                Debug.LogError("Loading Entity Scene failed because the entity header file was an old version: " + scene.SceneGUID);
                return;
            }

            LogResolving("ResolveScene (success)", scene.SceneGUID);

            ref var sceneMetaData = ref sceneMetaDataRef.Value;
        void UpdateSceneContentsChanged(Hash128 buildSettingGUID)
        {
#if UNITY_EDITOR
            Entities.With(m_ResolvedScenes).ForEach((Entity sceneEntity, ref SceneReference scene, ref ResolvedSceneHash resolvedScene) =>
            {
                LogResolving("Queuing UpdateSceneContentsChanged", scene.SceneGUID);
                var hash = EntityScenesPaths.GetSubSceneArtifactHash(scene.SceneGUID, buildSettingGUID, UnityEditor.Experimental.AssetDatabaseExperimental.ImportSyncMode.Queue);
                if ((hash != default) && (hash != resolvedScene.ArtifactHash))
                {
                    NotifySceneContentsHasChanged(scene.SceneGUID);
                }
            });
#endif

            if (m_ChangedScenes.Length != 0)
            {
                var sceneSystem = World.GetExistingSystem <SceneSystem>();
                foreach (var scene in m_ChangedScenes)
                {
                    var sceneEntity = sceneSystem.GetSceneEntity(scene);

                    // Don't touch it if the scene is under live link control (@Todo: SubSceneStreamingSystem.IgnoreTag could be live link specific?)
                    if (sceneEntity != Entity.Null && !EntityManager.HasComponent <DisableSceneResolveAndLoad>(sceneEntity))
                    {
                        var unloadFlags = SceneSystem.UnloadParameters.DestroySectionProxyEntities | SceneSystem.UnloadParameters.DontRemoveRequestSceneLoaded;
                        sceneSystem.UnloadScene(sceneEntity, unloadFlags);
                    }
                }
                m_ChangedScenes.Clear();
            }
        }
コード例 #8
0
        void ResolveScene(Entity sceneEntity, ref SceneReference scene, RequestSceneLoaded requestSceneLoaded, Hash128 artifactHash)
        {
            // Resolve first (Even if the file doesn't exist we want to stop continously trying to load the section)
            EntityManager.AddBuffer <ResolvedSectionEntity>(sceneEntity);

#if UNITY_EDITOR && !USE_SUBSCENE_EDITORBUNDLES
            EntityManager.AddComponentData(sceneEntity, new ResolvedSceneHash {
                ArtifactHash = artifactHash
            });

            UnityEditor.Experimental.AssetDatabaseExperimental.GetArtifactPaths(artifactHash, out var paths);

            var sceneHeaderPath = EntityScenesPaths.GetLoadPathFromArtifactPaths(paths, EntityScenesPaths.PathType.EntitiesHeader);
#else
            var sceneHeaderPath = EntityScenesPaths.GetLoadPath(scene.SceneGUID, EntityScenesPaths.PathType.EntitiesHeader, -1);
#endif

#if UNITY_ANDROID && !UNITY_EDITOR
            var uwrFile = new UnityWebRequest(sceneHeaderPath);
            uwrFile.downloadHandler = new DownloadHandlerBuffer();
            uwrFile.SendWebRequest();
            while (!uwrFile.isDone)
            {
            }

            if (uwrFile.isNetworkError || uwrFile.isHttpError)
            {
                Debug.LogError($"Loading Entity Scene failed because the entity header file could not be found: {scene.SceneGUID}\nNOTE: In order to load SubScenes in the player you have to use the new BuildSettings asset based workflow to build & run your player.\n{sceneHeaderPath}");
                return;
            }

            if (!BlobAssetReference <SceneMetaData> .TryRead(uwrFile.downloadHandler.data, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out var sceneMetaDataRef))
            {
                Debug.LogError("Loading Entity Scene failed because the entity header file was an old version: " + scene.SceneGUID);
                return;
            }
#else
            if (!File.Exists(sceneHeaderPath))
            {
                #if UNITY_EDITOR
                Debug.LogError($"Loading Entity Scene failed because the entity header file could not be found: {scene.SceneGUID}\n{sceneHeaderPath}");
                #else
                Debug.LogError($"Loading Entity Scene failed because the entity header file could not be found: {scene.SceneGUID}\nNOTE: In order to load SubScenes in the player you have to use the new BuildSettings asset based workflow to build & run your player.\n{sceneHeaderPath}");
                #endif
                return;
            }

            if (!BlobAssetReference <SceneMetaData> .TryRead(sceneHeaderPath, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out var sceneMetaDataRef))
            {
                Debug.LogError("Loading Entity Scene failed because the entity header file was an old version: " + scene.SceneGUID);
                return;
            }
#endif

            LogResolving("ResolveScene (success)", scene.SceneGUID);

            ref var sceneMetaData = ref sceneMetaDataRef.Value;
コード例 #9
0
        //TODO: There is too much code duplication here, refactor this to receive general artifacts from the editor
        unsafe void ReceiveSubSceneRefGUIDs(MessageEventArgs args)
        {
            fixed(byte *ptr = args.data)
            {
                var reader        = new UnsafeAppendBuffer.Reader(ptr, args.data.Length);
                var subSceneAsset = reader.ReadNext <ResolvedSubSceneID>();
                var sectionIndex  = reader.ReadNext <int>();

                reader.ReadNext(out NativeArray <RuntimeGlobalObjectId> objRefGUIDs, Allocator.Persistent);
                var refObjGUIDsPath = EntityScenesPaths.GetLiveLinkCachePath(subSceneAsset.TargetHash, EntityScenesPaths.PathType.EntitiesUnityObjectReferences, sectionIndex);

                // Not printing error because this can happen when running the same player multiple times on the same machine
                if (File.Exists(refObjGUIDsPath))
                {
                    LiveLinkMsg.LogInfo($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} but it already exists on disk");
                }
                else
                {
                    LiveLinkMsg.LogInfo($"ReceieveSubSceneRefGUIDs => {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash},");

                    var tempCachePath = GetTempCachePath();
                    using (var writer = new StreamBinaryWriter(tempCachePath))
                    {
                        writer.Write(objRefGUIDs.Length);
                        writer.WriteArray(objRefGUIDs);
                    }

                    try
                    {
                        File.Move(tempCachePath, refObjGUIDsPath);
                    }
                    catch (Exception e)
                    {
                        File.Delete(tempCachePath);
                        if (!File.Exists(refObjGUIDsPath))
                        {
                            Debug.LogError($"Failed to move temporary file. Exception: {e.Message}");
                            LiveLinkMsg.LogInfo($"Failed to move temporary file. Exception: {e.Message}");
                        }
                    }
                }

                if (!_WaitingForSubScenes.ContainsKey(subSceneAsset.SubSceneGUID))
                {
                    Debug.LogError($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} without requesting it");
                    LiveLinkMsg.LogInfo($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} without requesting it");
                    return;
                }

                var waitingSubScene = _WaitingForSubScenes[subSceneAsset.SubSceneGUID];

                waitingSubScene.SubSections.Add(objRefGUIDs);
                _WaitingForSubScenes[subSceneAsset.SubSceneGUID] = waitingSubScene;
            }
        }
        public static unsafe void WritePlayerLiveLinkCacheGUID()
        {
            CreatePlayerLiveLinkCacheDir();
            var cacheGUIDPath = $"{EntityScenesPaths.GetLiveLinkCacheDirPath()}/livelinkcacheguid";

            using (var stream = new StreamBinaryWriter(cacheGUIDPath))
            {
                Hash128 guid = LiveLinkCacheGUID;
                stream.WriteBytes(&guid, sizeof(Hash128));
            }
        }
コード例 #11
0
        unsafe void ReceiveResponseSubSceneTargetHash(MessageEventArgs args)
        {
            using (var subSceneAssets = args.ReceiveArray <ResolvedSubSceneID>())
            {
                foreach (var subSceneAsset in subSceneAssets)
                {
                    if (_WaitingForSubScenes.ContainsKey(subSceneAsset.SubSceneGUID))
                    {
                        return;
                    }

                    var headerPath = EntityScenesPaths.GetLiveLinkCachePath(subSceneAsset.TargetHash, EntityScenesPaths.PathType.EntitiesHeader, -1);

                    if (File.Exists(headerPath))
                    {
                        LiveLinkMsg.LogInfo($"ReceiveResponseSubSceneTargetHash => {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash}, File.Exists => 'True', {Path.GetFullPath(headerPath)}");

                        //TODO: This is a hack to make sure assets are managed by asset manifest when loading from cache for first run
                        if (!BlobAssetReference <SceneMetaData> .TryRead(headerPath, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out var sceneMetaDataRef))
                        {
                            Debug.LogError("Loading Entity Scene failed because the entity header file was an old version: " + subSceneAsset.SubSceneGUID);
                            return;
                        }

                        ref var sceneMetaData = ref sceneMetaDataRef.Value;

                        var waitingSubScene = new WaitingSubScene
                        {
                            TargetHash      = subSceneAsset.TargetHash,
                            SubSections     = new List <NativeArray <RuntimeGlobalObjectId> >(),
                            SubSectionCount = sceneMetaData.Sections.Length
                        };

                        for (int i = 0; i < sceneMetaData.Sections.Length; i++)
                        {
                            if (sceneMetaData.Sections[i].ObjectReferenceCount != 0)
                            {
                                var refObjGUIDsPath = EntityScenesPaths.GetLiveLinkCachePath(subSceneAsset.TargetHash, EntityScenesPaths.PathType.EntitiesUnityObjectReferences, i);
                                using (var reader = new StreamBinaryReader(refObjGUIDsPath))
                                {
                                    var numObjRefGUIDs = reader.ReadInt();
                                    NativeArray <RuntimeGlobalObjectId> objRefGUIDs = new NativeArray <RuntimeGlobalObjectId>(numObjRefGUIDs, Allocator.Persistent);
                                    reader.ReadArray(objRefGUIDs, numObjRefGUIDs);
                                    waitingSubScene.SubSections.Add(objRefGUIDs);
                                }
                            }
                            else
                            {
                                waitingSubScene.SubSections.Add(new NativeArray <RuntimeGlobalObjectId>(0, Allocator.Persistent));
                            }
                        }

                        _WaitingForSubScenes[subSceneAsset.SubSceneGUID] = waitingSubScene;
                    }
コード例 #12
0
        unsafe void ReceiveSubSceneHeader(MessageEventArgs args)
        {
            fixed(byte *ptr = args.data)
            {
                var reader          = new UnsafeAppendBuffer.Reader(ptr, args.data.Length);
                var subSceneAsset   = reader.ReadNext <ResolvedSubSceneID>();
                var subSectionCount = reader.ReadNext <int>();
                var headerPath      = EntityScenesPaths.GetLiveLinkCachePath(subSceneAsset.TargetHash, EntityScenesPaths.PathType.EntitiesHeader, -1);

                // Not printing error because this can happen when running the same player multiple times on the same machine
                if (File.Exists(headerPath))
                {
                    LiveLinkMsg.LogInfo($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} but it already exists on disk");
                }
                else
                {
                    var tempCachePath = GetTempCachePath();
                    LiveLinkMsg.LogInfo($"ReceiveSubSceneHeader => {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash}, '{tempCachePath}' => '{headerPath}'");

                    var stream = File.OpenWrite(tempCachePath);
                    stream.Write(args.data, reader.Offset, args.data.Length - reader.Offset);
                    stream.Close();
                    stream.Dispose();

                    try
                    {
                        File.Move(tempCachePath, headerPath);
                    }
                    catch (Exception e)
                    {
                        File.Delete(tempCachePath);
                        if (!File.Exists(headerPath))
                        {
                            Debug.LogError($"Failed to move temporary file. Exception: {e.Message}");
                            LiveLinkMsg.LogInfo($"Failed to move temporary file. Exception: {e.Message}");
                        }
                    }
                }

                if (!_WaitingForSubScenes.ContainsKey(subSceneAsset.SubSceneGUID))
                {
                    Debug.LogError($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} without requesting it");
                    LiveLinkMsg.LogInfo($"Received {subSceneAsset.SubSceneGUID} | {subSceneAsset.TargetHash} without requesting it");
                    return;
                }

                var waitingSubScene = _WaitingForSubScenes[subSceneAsset.SubSceneGUID];

                waitingSubScene.TargetHash      = subSceneAsset.TargetHash;
                waitingSubScene.SubSectionCount = subSectionCount;
                _WaitingForSubScenes[subSceneAsset.SubSceneGUID] = waitingSubScene;
            }
        }
        public static unsafe void ReadPlayerLiveLinkCacheGUID()
        {
            var cacheGUIDPath = $"{EntityScenesPaths.GetLiveLinkCacheDirPath()}/livelinkcacheguid";

            if (File.Exists(cacheGUIDPath))
            {
                using (var rdr = new StreamBinaryReader(cacheGUIDPath))
                {
                    Hash128 guid = default;
                    rdr.ReadBytes(&guid, sizeof(Hash128));
                    LiveLinkCacheGUID = guid;
                }
            }
        }
コード例 #14
0
        //@TODO: Support some sort of transaction like API so we can reload all changed things in batch.
        unsafe void ReceiveAsset(MessageEventArgs args)
        {
            LiveLinkMsg.LogReceived($"AssetBundle: '{args.data.Length}' bytes");

            fixed(byte *ptr = args.data)
            {
                var reader = new UnsafeAppendBuffer.Reader(ptr, args.data.Length);
                var asset  = reader.ReadNext <ResolvedAssetID>();
                var assetBundleCachePath = EntityScenesPaths.GetCachePath(asset.TargetHash);

                // Not printing error because this can happen when running the same player multiple times on the same machine
                if (File.Exists(assetBundleCachePath))
                {
                    LiveLinkMsg.LogInfo($"Received {asset.GUID} | {asset.TargetHash} but it already exists on disk");
                }
                else
                {
                    // cache: look up asset by target hash to see if the version we want is already on the target device
                    //if we already have the asset bundle revision we want, then just put that in the resolver as the active revision of the asset
                    // cache: if not in cache, write actual file to Application.persistentDatapath
                    var tempCachePath = EntityScenesPaths.GetTempCachePath();
                    LiveLinkMsg.LogInfo($"ReceiveAssetBundle => {asset.GUID} | {asset.TargetHash}, '{tempCachePath}' => '{assetBundleCachePath}'");

                    using (var stream = File.OpenWrite(tempCachePath))
                        stream.Write(args.data, reader.Offset, args.data.Length - reader.Offset);

                    try
                    {
                        File.Move(tempCachePath, assetBundleCachePath);
                    }
                    catch (Exception e)
                    {
                        File.Delete(tempCachePath);
                        if (!File.Exists(assetBundleCachePath))
                        {
                            Debug.LogError($"Failed to move temporary file. Source: {tempCachePath} | Destination: {assetBundleCachePath} - Exception: {e.Message}");
                            LiveLinkMsg.LogInfo($"Failed to move temporary file. Exception: {e.Message}");
                        }
                    }
                }

                if (!m_WaitingForAssets.ContainsKey(asset.GUID))
                {
                    LiveLinkMsg.LogInfo($"Received {asset.GUID} | {asset.TargetHash} without requesting it");
                }

                m_WaitingForAssets[asset.GUID] = asset.TargetHash;
            }
        }
        public static void ClearPlayerLiveLinkCache()
        {
            var cachePath = EntityScenesPaths.GetLiveLinkCacheDirPath();

            if (Directory.Exists(cachePath))
            {
                try
                {
                    Directory.Delete(cachePath, true);
                }
                catch (SystemException exception)
                {
                    Debug.LogError($"Failed to delete LiveLink cache! {exception.Message}");
                }
            }
        }
コード例 #16
0
ファイル: SubScene.cs プロジェクト: ctxdegithub/UnityEntities
        public void UpdateSceneEntities()
        {
#if UNITY_EDITOR
            var sceneHeaderPath = EntityScenesPaths.GetLoadPath(SceneGUID, EntityScenesPaths.PathType.EntitiesHeader, -1);
            m_SubSceneHeader = AssetDatabase.LoadAssetAtPath <SubSceneHeader>(sceneHeaderPath);
#endif

            if (_SceneEntityManager != null && _SceneEntityManager.IsCreated)
            {
                foreach (var sceneEntity in _SceneEntities)
                {
                    _SceneEntityManager.DestroyEntity(sceneEntity);
                }
            }
            _SceneEntities.Clear();
            _SceneEntityManager = null;

            DefaultWorldInitialization.DefaultLazyEditModeInitialize();
            if (World.Active != null && m_SubSceneHeader != null)
            {
                _SceneEntityManager = World.Active.EntityManager;

                for (int i = 0; i < m_SubSceneHeader.Sections.Length; ++i)
                {
                    var sceneEntity = _SceneEntityManager.CreateEntity();
                    #if UNITY_EDITOR
                    _SceneEntityManager.SetName(sceneEntity, i == 0 ? $"Scene: {SceneName}" : $"Scene: {SceneName} ({i})");
                    #endif

                    _SceneEntities.Add(sceneEntity);
                    _SceneEntityManager.AddComponentObject(sceneEntity, this);

                    if (AutoLoadScene)
                    {
                        _SceneEntityManager.AddComponentData(sceneEntity, new RequestSceneLoaded());
                    }

                    _SceneEntityManager.AddComponentData(sceneEntity, m_SubSceneHeader.Sections[i]);
                    _SceneEntityManager.AddComponentData(sceneEntity, new SceneBoundingVolume {
                        Value = m_SubSceneHeader.Sections[i].BoundingVolume
                    });
                }
            }
        }
コード例 #17
0
        unsafe void ReceiveBuildArtifact(MessageEventArgs args)
        {
            fixed(byte *ptr = args.data)
            {
                LiveLinkMsg.LogInfo($"ReceiveBuildArtifact => Buffer Size: {args.data.Length}");
                var reader = new UnsafeAppendBuffer.Reader(ptr, args.data.Length);

                reader.ReadNext(out string artifactFileName);
                string artifactPath = EntityScenesPaths.ComposeLiveLinkCachePath(artifactFileName);

                if (!File.Exists(artifactPath))
                {
                    LiveLinkMsg.LogInfo($"ReceiveBuildArtifact => {artifactPath}");

                    var tempCachePath = GetTempCachePath();

                    try
                    {
                        var stream = File.OpenWrite(tempCachePath);
                        stream.Write(args.data, reader.Offset, args.data.Length - reader.Offset);
                        stream.Close();
                        stream.Dispose();

                        File.Move(tempCachePath, artifactPath);

                        LiveLinkMsg.LogInfo($"ReceiveBuildArtifact => Successfully written to disc.");
                    }
                    catch (Exception e)
                    {
                        if (File.Exists(tempCachePath))
                        {
                            File.Delete(tempCachePath);
                        }

                        if (!File.Exists(artifactPath))
                        {
                            Debug.LogError($"Failed to move temporary file. Exception: {e.Message}");
                        }
                    }
                }
            }
        }
コード例 #18
0
        int CreateAsyncLoadScene(Entity entity)
        {
            for (int i = 0; i != m_Streams.Length; i++)
            {
                if (m_Streams[i].Operation != null)
                {
                    continue;
                }

                var sceneData = EntityManager.GetComponentData <SceneData>(entity);

                var entitiesBinaryPath = EntityScenesPaths.GetLoadPath(sceneData.SceneGUID, EntityScenesPaths.PathType.EntitiesBinary, sceneData.SubSectionIndex);
                var resourcesPath      = EntityScenesPaths.GetLoadPath(sceneData.SceneGUID, EntityScenesPaths.PathType.EntitiesSharedComponents, sceneData.SubSectionIndex);
                var entityManager      = m_Streams[i].World.GetOrCreateManager <EntityManager>();

                m_Streams[i].Operation   = new AsyncLoadSceneOperation(entitiesBinaryPath, sceneData.FileSize, sceneData.SharedComponentCount, resourcesPath, entityManager);
                m_Streams[i].SceneEntity = entity;
                return(i);
            }

            return(-1);
        }
コード例 #19
0
        internal static SceneBundleHandle[] LoadSceneBundles(string mainBundlePath, NativeArray <Entities.Hash128> sharedBundles, bool blocking)
        {
            var hasMainBundle = !string.IsNullOrEmpty(mainBundlePath);
            var bundles       = new SceneBundleHandle[sharedBundles.Length + (hasMainBundle ? 1 : 0)];

            if (hasMainBundle)
            {
                LogBundle($"Request main bundle {mainBundlePath}");
            }

            if (sharedBundles.IsCreated)
            {
                for (int i = 0; i < sharedBundles.Length; i++)
                {
                    var path = $"{Application.streamingAssetsPath}/{EntityScenesPaths.RelativePathFolderFor(sharedBundles[i], EntityScenesPaths.PathType.EntitiesSharedReferencesBundle, -1)}";
                    LogBundle($"Request dependency {mainBundlePath}");
                    bundles[i + 1] = CreateOrRetainBundle(path);
                }
            }

            if (hasMainBundle)
            {
                bundles[0] = CreateOrRetainBundle(mainBundlePath);
            }

            if (blocking)
            {
                foreach (var b in bundles)
                {
                    var forceLoad = b.AssetBundle;
                    if (forceLoad == null)
                    {
                        Debug.LogWarning($"Failed to load asset bundle at path {b._bundlePath}");
                    }
                }
            }
            return(bundles);
        }
コード例 #20
0
        internal static void RequestLoadAndPollSceneMetaData(EntityManager EntityManager, Entity sceneEntity, Hash128 sceneGUID)
        {
            var sceneHeaderPath = EntityScenesPaths.GetLoadPath(sceneGUID, EntityScenesPaths.PathType.EntitiesHeader, -1);

            RequestSceneHeader requestSceneHeader;

            if (!EntityManager.HasComponent <RequestSceneHeader>(sceneEntity))
            {
                requestSceneHeader.IOHandle = IOService.RequestAsyncRead(sceneHeaderPath).m_Handle;
                EntityManager.AddComponentData(sceneEntity, requestSceneHeader);
            }
            else
            {
                requestSceneHeader = EntityManager.GetComponentData <RequestSceneHeader>(sceneEntity);
            }

            var asyncOp = new AsyncOp()
            {
                m_Handle = requestSceneHeader.IOHandle
            };
            var sceneHeaderStatus = asyncOp.GetStatus();

            if (sceneHeaderStatus <= AsyncOp.Status.InProgress)
            {
                return;
            }

            if (sceneHeaderStatus != AsyncOp.Status.Success)
            {
                Debug.LogError($"Loading Entity Scene failed because the entity header file could not be read: guid={sceneGUID}.");
            }

            // Even if the file doesn't exist we want to stop continously trying to load the scene metadata
            EntityManager.AddComponentData(sceneEntity, new SceneMetaDataLoaded()
            {
                Success = sceneHeaderStatus == AsyncOp.Status.Success
            });
        }
コード例 #21
0
ファイル: SubScene.cs プロジェクト: ctxdegithub/UnityEntities
        void OnEnable()
        {
    #if UNITY_EDITOR
            if (UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetPrefabStage(gameObject) != null)
            {
                return;
            }

            m_SubSceneHeader = null;
            if (SceneAsset == null)
            {
                return;
            }

            foreach (var subscene in m_AllSubScenes)
            {
                if (subscene.SceneAsset == SceneAsset)
                {
                    Debug.LogWarning($"A sub-scene can not include the same scene ('{EditableScenePath}') multiple times.", this);
                    return;
                }
            }

            m_AllSubScenes.Add(this);

            var sceneHeaderPath = EntityScenesPaths.GetLoadPath(SceneGUID, EntityScenesPaths.PathType.EntitiesHeader, -1);
            m_SubSceneHeader = AssetDatabase.LoadAssetAtPath <SubSceneHeader>(sceneHeaderPath);

            if (m_SubSceneHeader == null)
            {
                Debug.LogWarning($"Sub-scene '{EditableScenePath}' has no valid header at '{sceneHeaderPath}'. Please rebuild the Entity Cache.", this);
                return;
            }
    #endif

            UpdateSceneEntities();
        }
コード例 #22
0
        public static bool ResolveSceneSections(EntityManager EntityManager, Entity sceneEntity, Hash128 sceneGUID, RequestSceneLoaded requestSceneLoaded, Hash128 artifactHash)
        {
            // Resolve first (Even if the file doesn't exist we want to stop continously trying to load the section)
            EntityManager.AddBuffer <ResolvedSectionEntity>(sceneEntity);

    #if UNITY_EDITOR && !USE_SUBSCENE_EDITORBUNDLES
            EntityManager.AddComponentData(sceneEntity, new ResolvedSceneHash {
                ArtifactHash = artifactHash
            });

            AssetDatabaseCompatibility.GetArtifactPaths(artifactHash, out var paths);

            var sceneHeaderPath = EntityScenesPaths.GetLoadPathFromArtifactPaths(paths, EntityScenesPaths.PathType.EntitiesHeader);
    #else
            var sceneHeaderPath = EntityScenesPaths.GetLoadPath(sceneGUID, EntityScenesPaths.PathType.EntitiesHeader, -1);
    #endif

            // @TODO: AsyncReadManager currently crashes with empty path.
            //        It should be possible to remove this after that is fixed.
            if (String.IsNullOrEmpty(sceneHeaderPath))
            {
                Debug.LogError($"Loading Entity Scene failed because the entity header file couldn't be resolved: guid={sceneGUID}.");
                return(false);
            }

            if (!BlobAssetReference <SceneMetaData> .TryRead(sceneHeaderPath, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out var sceneMetaDataRef))
            {
    #if UNITY_EDITOR
                Debug.LogError($"Loading Entity Scene failed because the entity header file was an old version or doesn't exist: guid={sceneGUID} path={sceneHeaderPath}");
    #else
                Debug.LogError($"Loading Entity Scene failed because the entity header file was an old version or doesn't exist: {sceneGUID}\nNOTE: In order to load SubScenes in the player you have to use the new BuildConfiguration asset based workflow to build & run your player.\n{sceneHeaderPath}");
    #endif
                return(false);
            }

            ref var sceneMetaData = ref sceneMetaDataRef.Value;
コード例 #23
0
        void LoadAssetBundles(NativeArray <ResolvedAssetID> assets)
        {
            LiveLinkMsg.LogInfo("--- Begin Load asset bundles");

            var patchAssetBundles     = new List <AssetBundle>();
            var patchAssetBundlesPath = new List <string>();
            var newAssetBundles       = new List <Hash128>();
            var assetBundleToValidate = new List <Hash128>();


            foreach (var asset in assets)
            {
                var assetGUID            = asset.GUID;
                var targetHash           = asset.TargetHash;
                var assetBundleCachePath = EntityScenesPaths.GetCachePath(targetHash);

                //if we already loaded an asset bundle and we just need a refresh
                var oldAssetBundle = globalAssetObjectResolver.GetAssetBundle(assetGUID);
                if (oldAssetBundle != null)
                {
                    if (oldAssetBundle.isStreamedSceneAssetBundle)
                    {
                        LiveLinkMsg.LogInfo($"Unloading scene bundle: {assetGUID}");
                        var sceneSystem = World.GetExistingSystem <SceneSystem>();
                        sceneSystem.UnloadScene(assetGUID);
                        globalAssetObjectResolver.UnloadAsset(assetGUID);
                        continue;
                    }
                    else
                    {
                        LiveLinkMsg.LogInfo($"patching asset bundle: {assetGUID}");

                        patchAssetBundles.Add(oldAssetBundle);
                        patchAssetBundlesPath.Add(assetBundleCachePath);

                        globalAssetObjectResolver.UpdateTargetHash(assetGUID, targetHash);
                        newAssetBundles.Add(assetGUID);
                    }
                }
                else
                {
                    LiveLinkMsg.LogInfo($"Loaded asset bundle: {assetGUID}");

                    var loadedAssetBundle = AssetBundle.LoadFromFile(assetBundleCachePath);
                    globalAssetObjectResolver.AddAsset(assetGUID, targetHash, null, loadedAssetBundle);
                    newAssetBundles.Add(assetGUID);
                }

                assetBundleToValidate.Add(assetGUID);

                //@TODO: Keep a hashtable of guid -> entity?
                Entities.ForEach((Entity entity, ref ResourceGUID guid) =>
                {
                    if (guid.Guid == assetGUID)
                    {
                        EntityManager.AddComponentData(entity, new ResourceLoaded());
                    }
                });
            }


            AssetBundleUtility.PatchAssetBundles(patchAssetBundles.ToArray(), patchAssetBundlesPath.ToArray());

            foreach (var assetGUID in newAssetBundles)
            {
                var assetBundle = globalAssetObjectResolver.GetAssetBundle(assetGUID);
                if (assetBundle == null)
                {
                    Debug.LogError($"Could not load requested asset bundle.'");
                    return;
                }

                if (!assetBundle.isStreamedSceneAssetBundle)
                {
                    var loadedManifest = assetBundle.LoadAsset <AssetObjectManifest>(assetGUID.ToString());
                    if (loadedManifest == null)
                    {
                        Debug.LogError($"Loaded {assetGUID} failed to load ObjectManifest");
                        return;
                    }

                    globalAssetObjectResolver.UpdateObjectManifest(assetGUID, loadedManifest);
                }
            }

            foreach (var assetGUID in assetBundleToValidate)
            {
                globalAssetObjectResolver.Validate(assetGUID);
            }

            LiveLinkMsg.LogInfo("--- End Load asset bundles");
        }
コード例 #24
0
        //@TODO: What happens if we change source assets between queuing a request for the first time and it being resolved?

        protected override void OnUpdate()
        {
            //TODO: How can we disable systems in specific builds?
#if !UNITY_EDITOR
            Enabled = !LiveLinkUtility.LiveLinkEnabled;
            if (!Enabled)
            {
                return;
            }
#else
            SceneWithBuildConfigurationGUIDs.ValidateBuildSettingsCache();
#endif
            var buildConfigurationGUID = World.GetExistingSystem <SceneSystem>().BuildConfigurationGUID;

            UpdateSceneContentsChanged(buildConfigurationGUID);

#if UNITY_EDITOR && !USE_SUBSCENE_EDITORBUNDLES
            Entities.With(m_ImportingScenes).ForEach((Entity sceneEntity, ref SceneReference scene, ref RequestSceneLoaded requestSceneLoaded) =>
            {
                var hash = EntityScenesPaths.GetSubSceneArtifactHash(scene.SceneGUID, buildConfigurationGUID, ImportMode.NoImport);
                if (hash.IsValid)
                {
                    LogResolving("Polling Importing (completed)", scene.SceneGUID);
                    ResolveScene(sceneEntity, ref scene, requestSceneLoaded, hash);
                }
                else
                {
                    LogResolving("Polling Importing (not complete)", scene.SceneGUID);
                }
            });
#endif


            //@TODO: Temporary workaround to prevent crash after build player
            if (m_ScenesToRequest.IsEmptyIgnoreFilter)
            {
                return;
            }

            // We are seeing this scene for the first time, so we need to schedule a request.
            Entities.With(m_ScenesToRequest).ForEach((Entity sceneEntity, ref SceneReference scene, ref RequestSceneLoaded requestSceneLoaded) =>
            {
#if UNITY_EDITOR && !USE_SUBSCENE_EDITORBUNDLES
                var blocking   = (requestSceneLoaded.LoadFlags & SceneLoadFlags.BlockOnImport) != 0;
                var importMode = blocking ? ImportMode.Synchronous : ImportMode.Asynchronous;

                var hash = EntityScenesPaths.GetSubSceneArtifactHash(scene.SceneGUID, buildConfigurationGUID, importMode);
                if (hash.IsValid)
                {
                    LogResolving(blocking ? "Blocking import (completed)" : "Queue not yet requested (completed)", scene.SceneGUID);
                    ResolveScene(sceneEntity, ref scene, requestSceneLoaded, hash);
                }
                else
                {
                    LogResolving(blocking ? "Blocking import (failed)" : "Queue not yet requested (not complete)", scene.SceneGUID);
                }
#else
                ResolveScene(sceneEntity, ref scene, requestSceneLoaded, new Hash128());
#endif
            });
            EntityManager.AddComponent(m_ScenesToRequest, ComponentType.ReadWrite <ResolvedSectionEntity>());
        }
コード例 #25
0
        public void UpdateSceneEntities(bool warnIfMissing = false)
        {
#if UNITY_EDITOR
            var sceneHeaderPath = EntityScenesPaths.GetLoadPath(SceneGUID, EntityScenesPaths.PathType.EntitiesHeader, -1);
            m_SubSceneHeader = AssetDatabase.LoadAssetAtPath <SubSceneHeader>(sceneHeaderPath);
#endif
            if (warnIfMissing && m_SubSceneHeader == null)
            {
#if UNITY_EDITOR
                Debug.LogWarning($"Sub-scene '{EditableScenePath}' has no valid header at '{sceneHeaderPath}'. Please rebuild the Entity Cache.", this);
#else
                Debug.LogWarning($"Sub-scene '{name}' has no valid header. Please rebuild the Entity Cache.", this);
#endif
            }


            if (_SceneEntityManager != null && _SceneEntityManager.IsCreated)
            {
                foreach (var sceneEntity in _SceneEntities)
                {
                    _SceneEntityManager.DestroyEntity(sceneEntity);
                }
            }
            _SceneEntities.Clear();
            _SceneEntityManager = null;

            DefaultWorldInitialization.DefaultLazyEditModeInitialize();
            if (World.Active != null)
            {
                _SceneEntityManager = World.Active.EntityManager;

                if (m_SubSceneHeader != null)
                {
                    for (int i = 0; i < m_SubSceneHeader.Sections.Length; ++i)
                    {
                        var sceneEntity = _SceneEntityManager.CreateEntity();
                        #if UNITY_EDITOR
                        _SceneEntityManager.SetName(sceneEntity, i == 0 ? $"Scene: {SceneName}" : $"Scene: {SceneName} ({i})");
                        #endif

                        _SceneEntities.Add(sceneEntity);
                        _SceneEntityManager.AddComponentObject(sceneEntity, this);

                        if (AutoLoadScene)
                        {
                            _SceneEntityManager.AddComponentData(sceneEntity, new RequestSceneLoaded());
                        }

                        _SceneEntityManager.AddComponentData(sceneEntity, m_SubSceneHeader.Sections[i]);
                        _SceneEntityManager.AddComponentData(sceneEntity, new SceneBoundingVolume {
                            Value = m_SubSceneHeader.Sections[i].BoundingVolume
                        });
                    }
                }
                else
                {
                    var sceneEntity = _SceneEntityManager.CreateEntity();
                    #if UNITY_EDITOR
                    _SceneEntityManager.SetName(sceneEntity, "Scene: {SceneName}");
                    #endif

                    _SceneEntities.Add(sceneEntity);
                    _SceneEntityManager.AddComponentObject(sceneEntity, this);
                }
            }
        }
コード例 #26
0
        public unsafe static bool ResolveSceneSections(EntityManager EntityManager, Entity sceneEntity, Hash128 sceneGUID, RequestSceneLoaded requestSceneLoaded, Hash128 artifactHash)
        {
            // Resolve first (Even if the file doesn't exist we want to stop continously trying to load the section)
            var bufLen = EntityManager.AddBuffer <ResolvedSectionEntity>(sceneEntity).Length;

            Assert.AreEqual(0, bufLen);

            var sceneHeaderPath = "";

#if UNITY_EDITOR
            string[] paths = null;
#endif

            bool useStreamingAssetPath = true;
#if !UNITY_DOTSRUNTIME
            useStreamingAssetPath = SceneBundleHandle.UseAssetBundles;
#endif
            if (useStreamingAssetPath)
            {
                sceneHeaderPath = EntityScenesPaths.GetLoadPath(sceneGUID, EntityScenesPaths.PathType.EntitiesHeader, -1);
            }
            else
            {
#if UNITY_EDITOR
                AssetDatabaseCompatibility.GetArtifactPaths(artifactHash, out paths);
                sceneHeaderPath = EntityScenesPaths.GetLoadPathFromArtifactPaths(paths, EntityScenesPaths.PathType.EntitiesHeader);
#endif
            }

            EntityManager.AddComponentData(sceneEntity, new ResolvedSceneHash {
                ArtifactHash = artifactHash
            });

            var group = EntityManager.AddBuffer <LinkedEntityGroup>(sceneEntity);
            Assert.AreEqual(0, group.Length);
            group.Add(sceneEntity);

            // @TODO: AsyncReadManager currently crashes with empty path.
            //        It should be possible to remove this after that is fixed.
            if (String.IsNullOrEmpty(sceneHeaderPath))
            {
#if UNITY_EDITOR
                var scenePath = AssetDatabaseCompatibility.GuidToPath(sceneGUID);
                var logPath   = System.IO.Path.GetFullPath(System.IO.Path.Combine(UnityEngine.Application.dataPath, "../Logs"));
                Debug.LogError($"Loading Entity Scene failed because the entity header file couldn't be resolved. This might be caused by a failed import of the entity scene. Please take a look at the SubScene MonoBehaviour that references this scene or at the asset import worker log in {logPath}. scenePath={scenePath} guid={sceneGUID}");
#else
                Debug.LogError($"Loading Entity Scene failed because the entity header file couldn't be resolved: guid={sceneGUID}.");
#endif
                return(false);
            }

#if !UNITY_DOTSRUNTIME
            if (!BlobAssetReference <SceneMetaData> .TryRead(sceneHeaderPath, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out var sceneMetaDataRef))
            {
#if UNITY_EDITOR
                Debug.LogError($"Loading Entity Scene failed because the entity header file was an old version or doesn't exist: guid={sceneGUID} path={sceneHeaderPath}");
#else
                Debug.LogError($"Loading Entity Scene failed because the entity header file was an old version or doesn't exist: {sceneGUID}\nNOTE: In order to load SubScenes in the player you have to use the new BuildConfiguration asset based workflow to build & run your player.\n{sceneHeaderPath}");
#endif
                return(false);
            }
#else
            Assert.IsTrue(EntityManager.HasComponent <RequestSceneHeader>(sceneEntity), "You may only resolve a scene if the entity has a RequestSceneHeader component");
            Assert.IsTrue(EntityManager.HasComponent <SceneMetaDataLoaded>(sceneEntity), "You may only resolve a scene if the entity has a SceneMetaDataLoaded component");
            var sceneMetaDataLoaded = EntityManager.GetComponentData <SceneMetaDataLoaded>(sceneEntity);
            if (!sceneMetaDataLoaded.Success)
            {
                return(false);
            }

            var requestSceneHeader = EntityManager.GetComponentData <RequestSceneHeader>(sceneEntity);
            var sceneMetaDataRef   = default(BlobAssetReference <SceneMetaData>);
            var asyncOp            = new AsyncOp()
            {
                m_Handle = requestSceneHeader.IOHandle
            };
            using (asyncOp)
            {
                unsafe
                {
                    asyncOp.GetData(out var sceneData, out var sceneDataSize);

                    if (!BlobAssetReference <SceneMetaData> .TryRead(sceneData, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out sceneMetaDataRef))
                    {
                        Debug.LogError($"Loading Entity Scene failed because the entity header file was an old version or doesn't exist: {sceneGUID}\nNOTE: In order to load SubScenes in the player you have to use the new BuildConfiguration asset based workflow to build & run your player.\n{sceneHeaderPath}");
                        return(false);
                    }
                }
            }
#endif

            ref var sceneMetaData = ref sceneMetaDataRef.Value;