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)); }
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)); }
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"); }
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;