public static Hash128 GetSubSceneArtifactHash(Hash128 sceneGUID, Hash128 buildConfigurationGUID, ImportMode importMode)
        {
            var guid = SceneWithBuildConfigurationGUIDs.EnsureExistsFor(sceneGUID, buildConfigurationGUID);

            if (!s_HashToString.TryGetValue(guid, out var guidString))
            {
                guidString = s_HashToString[guid] = guid.ToString();
            }
            return(AssetDatabaseCompatibility.GetArtifactHash(guidString, SubSceneImporterType, importMode));
        }
Ejemplo n.º 2
0
        public AssetDependencyTracker(Type importerType, string progressSummary)
        {
            _AssetImportType = importerType;
            _ProgressID      = -1;
            _ProgressSummary = progressSummary;

            _AllAssets     = new NativeMultiHashMap <GUID, ReportedValue>(1024, Allocator.Persistent);
            _InProgress    = new NativeList <GUID>(1024, Allocator.Persistent);
            _ArtifactCache = new NativeList <Hash128>(1024, Allocator.Persistent);
            _IsAssetWorker = AssetDatabaseCompatibility.IsAssetImportWorkerProcess();
        }
        internal static void ValidateBuildSettingsCache()
        {
            // Invalidate cache if we had an asset refresh
            var refreshDelta = AssetDatabaseCompatibility.GetArtifactDependencyVersion();

            if (s_AssetRefreshCounter != refreshDelta)
            {
                s_BuildConfigurationCreated.Clear();
            }

            s_AssetRefreshCounter = refreshDelta;
        }
        static unsafe void RegisterPlatformDependency()
        {
            var activeBuildTarget = EditorUserBuildSettings.activeBuildTarget.ToString();

            UnityEngine.Hash128 hash = default;
            fixed(char *str = activeBuildTarget)
            {
                HashUnsafeUtilities.ComputeHash128(str, (ulong)(sizeof(char) * activeBuildTarget.Length), &hash);
            }

            AssetDatabaseCompatibility.RegisterCustomDependency(livelinkBuildTargetDependencyName, hash);
        }
        public static Hash128 GetSubSceneArtifactHash(Hash128 sceneGUID, Hash128 buildConfigurationGUID, bool isBuildingForEditor, ImportMode importMode)
        {
            var guid = SceneWithBuildConfigurationGUIDs.EnsureExistsFor(sceneGUID, buildConfigurationGUID, isBuildingForEditor, out var mustRequestRefresh);

            if (mustRequestRefresh)
            {
                UnityEditor.AssetDatabase.Refresh();
            }

            if (!s_HashToString.TryGetValue(guid, out var guidString))
            {
                guidString = s_HashToString[guid] = guid.ToString();
            }
            return(AssetDatabaseCompatibility.GetArtifactHash(guidString, SubSceneImporterType, importMode));
        }
Ejemplo n.º 6
0
        private static unsafe void WriteEntitySceneWithBuildConfig(Hash128 guid, SceneWithBuildConfigurationGUIDs sceneWithBuildConfigurationGUIDs, string path)
        {
            var previousPath = AssetDatabaseCompatibility.GuidToPath(guid);

            if (!string.IsNullOrEmpty(previousPath) && previousPath != path)
            {
                UnityEngine.Debug.LogError($"EntitySceneWithBuildConfig guid is not unique {guid}. ScenePath: '{AssetDatabaseCompatibility.GuidToPath(sceneWithBuildConfigurationGUIDs.SceneGUID)}' Conflicting GUID: '{previousPath}'");
            }

            Directory.CreateDirectory(k_SceneDependencyCachePath);
            using (var writer = new StreamBinaryWriter(path))
            {
                writer.WriteBytes(&sceneWithBuildConfigurationGUIDs, sizeof(SceneWithBuildConfigurationGUIDs));
            }
            File.WriteAllText(path + ".meta",
                              $"fileFormatVersion: 2\nguid: {guid}\nDefaultImporter:\n  externalObjects: {{}}\n  userData:\n  assetBundleName:\n  assetBundleVariant:\n");
        }
Ejemplo n.º 7
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;
        protected override void OnUpdate()
        {
            SceneWithBuildConfigurationGUIDs.ValidateBuildSettingsCache();

            var sceneSystem            = World.GetExistingSystem <SceneSystem>();
            var buildConfigurationGUID = sceneSystem.BuildConfigurationGUID;

            // Add scene entities that haven't been encountered yet
            if (!m_AddScenes.IsEmptyIgnoreFilter)
            {
                //@TODO: Should use Entities.ForEach but we are missing
                // 1. Entities.ForEach support with execute always (ILPP compilation not taking effect on first domain reload)
                // 2. Entities.ForEach not supporting explicit queries

                using (var addScenes = m_AddScenes.ToEntityArray(Allocator.TempJob))
                {
                    var trackerStates = new NativeArray <AssetDependencyTrackerState>(addScenes.Length, Allocator.Temp);
                    for (int i = 0; i != addScenes.Length; i++)
                    {
                        var sceneEntity        = addScenes[i];
                        var scene              = EntityManager.GetComponentData <SceneReference>(sceneEntity);
                        var requestSceneLoaded = EntityManager.GetComponentData <RequestSceneLoaded>(sceneEntity);

                        var guid = SceneWithBuildConfigurationGUIDs.EnsureExistsFor(scene.SceneGUID,
                                                                                    buildConfigurationGUID, out var requireRefresh);
                        var async = (requestSceneLoaded.LoadFlags & SceneLoadFlags.BlockOnImport) == 0;

                        LogResolving(async ? "Adding Async" : "Adding Sync", guid);

                        _AssetDependencyTracker.Add(guid, sceneEntity, async);
                        if (requireRefresh)
                        {
                            _AssetDependencyTracker.RequestRefresh();
                        }

                        trackerStates[i] = new AssetDependencyTrackerState {
                            SceneAndBuildConfigGUID = guid
                        };
                    }

                    EntityManager.AddComponentData(m_AddScenes, trackerStates);
                    trackerStates.Dispose();
                }
            }

            // Remove scene entities that were added and should no longer be tracked
            if (!m_RemoveScenes.IsEmptyIgnoreFilter)
            {
                using (var removeEntities = m_RemoveScenes.ToEntityArray(Allocator.TempJob))
                    using (var removeGuids =
                               m_RemoveScenes.ToComponentDataArray <AssetDependencyTrackerState>(Allocator.TempJob))
                    {
                        for (int i = 0; i != removeEntities.Length; i++)
                        {
                            LogResolving("Removing", removeGuids[i].SceneAndBuildConfigGUID);
                            _AssetDependencyTracker.Remove(removeGuids[i].SceneAndBuildConfigGUID, removeEntities[i]);
                        }
                    }

                EntityManager.RemoveComponent <AssetDependencyTrackerState>(m_RemoveScenes);
            }

            // Process any scenes that have completed their asset import
            var isDone = _AssetDependencyTracker.GetCompleted(_Changed);

            foreach (var change in _Changed)
            {
                var sceneEntity = change.UserKey;
                LogResolving($"Resolving: {change.Asset} -> {change.ArtifactID}");

                if (!m_ValidSceneMask.Matches(sceneEntity))
                {
                    throw new InvalidOperationException("entity should have been removed from tracker already");
                }

                // Unload any previous state
                var unloadFlags = SceneSystem.UnloadParameters.DestroySectionProxyEntities |
                                  SceneSystem.UnloadParameters.DontRemoveRequestSceneLoaded;
                sceneSystem.UnloadScene(sceneEntity, unloadFlags);

                // Resolve new state
                var scene   = EntityManager.GetComponentData <SceneReference>(change.UserKey);
                var request = EntityManager.GetComponentData <RequestSceneLoaded>(change.UserKey);
                if (change.ArtifactID != default)
                {
                    ResolveSceneSectionUtility.ResolveSceneSections(EntityManager, change.UserKey, scene.SceneGUID,
                                                                    request, change.ArtifactID);
                }
                else
                {
                    Debug.LogError(
                        $"Failed to import entity scene because the automatically generated SceneAndBuildConfigGUID asset was not present: '{AssetDatabaseCompatibility.GuidToPath(scene.SceneGUID)}' -> '{AssetDatabaseCompatibility.GuidToPath(change.Asset)}'");
                }
            }

            if (!isDone)
            {
                EditorUpdateUtility.EditModeQueuePlayerLoopUpdate();
            }
        }
        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;