public void SubScene_WithDependencyOnAsset_IsInvalidatedWhenAssetChanges() { var subScene = SubSceneTestsHelper.CreateSubSceneFromObjects(ref m_TempAssets, "SubScene", false, () => { var go = new GameObject(); var authoring = go.AddComponent <DependencyTestAuthoring>(); authoring.Asset = m_Texture1; return(new List <GameObject> { go }); }); var buildSettings = default(Unity.Entities.Hash128); var hash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.Synchronous); Assert.IsTrue(hash.IsValid); m_Texture1.wrapMode = m_Texture1.wrapMode == TextureWrapMode.Repeat ? TextureWrapMode.Mirror : TextureWrapMode.Repeat; AssetDatabase.SaveAssets(); var newHash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.NoImport); Assert.AreNotEqual(hash, newHash); Assert.IsFalse(newHash.IsValid); }
public void SubScene_WithDependencyOnAssetInScene_Reimport_EndToEnd() { var subScene = SubSceneTestsHelper.CreateSubSceneFromObjects(ref m_TempAssets, "SubScene", false, () => { var go = new GameObject(); var authoring = go.AddComponent <DependencyTestAuthoring>(); var sphereHolder = GameObject.CreatePrimitive(PrimitiveType.Sphere); authoring.Asset = sphereHolder.GetComponent <MeshFilter>().sharedMesh; UnityEngine.Object.DestroyImmediate(sphereHolder); return(new List <GameObject> { go }); }); var buildSettings = default(Unity.Entities.Hash128); var originalHash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.Synchronous); Assert.IsTrue(originalHash.IsValid); SubSceneInspectorUtility.ForceReimport(new [] { subScene }); var newHashCreated = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.Synchronous); Assert.IsTrue(newHashCreated.IsValid); Assert.AreNotEqual(originalHash, newHashCreated); SubSceneInspectorUtility.ForceReimport(new [] { subScene }); var newHashUpdated = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.Synchronous); Assert.IsTrue(newHashUpdated.IsValid); Assert.AreNotEqual(newHashCreated, newHashUpdated); Assert.AreNotEqual(originalHash, newHashUpdated); }
public void SubScene_WithoutContents_DeletingSceneAssetUnloadsScene() { var subScene = SubSceneTestsHelper.CreateSubSceneFromObjects(ref m_TempAssets, "SubScene", false, null); subScene.AutoLoadScene = false; subScene.gameObject.SetActive(false); var world = World.DefaultGameObjectInjectionWorld; var sceneSystem = world.GetOrCreateSystem <SceneSystem>(); var sceneEntity = sceneSystem.LoadSceneAsync(subScene.SceneGUID, new SceneSystem.LoadParameters { Flags = SceneLoadFlags.BlockOnImport | SceneLoadFlags.BlockOnStreamIn }); Assert.IsFalse(sceneSystem.IsSceneLoaded(sceneEntity), "Scene should not be loaded yet."); // TODO: Editor doesn't update if it doesn't have focus, so we must explicitly update the world to process the load. world.Update(); Assert.IsTrue(sceneSystem.IsSceneLoaded(sceneEntity), "Failed to load scene"); AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(subScene.SceneAsset)); // Block the import of this subscene so that we can get a single-frame result for this test var hash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, sceneSystem.BuildConfigurationGUID, ImportMode.Synchronous); Assert.IsTrue(hash.IsValid, "Failed to import SubScene."); LogAssert.Expect(LogType.Error, new Regex("Loading Entity Scene failed.*")); // TODO: Editor doesn't update if it doesn't have focus, so we must explicitly update the world to process the load. world.Update(); Assert.IsFalse(sceneSystem.IsSceneLoaded(sceneEntity), "Scene should not be loaded"); }
public void SectionMetadata() { using (var world = TestWorldSetup.CreateEntityWorld("World", false)) { var resolveParams = new SceneSystem.LoadParameters { Flags = SceneLoadFlags.BlockOnImport | SceneLoadFlags.DisableAutoLoad }; var sceneSystem = world.GetOrCreateSystem <SceneSystem>(); var sceneEntity = sceneSystem.LoadSceneAsync(SceneGUID, resolveParams); world.Update(); var manager = world.EntityManager; var sectionEntities = manager.GetBuffer <ResolvedSectionEntity>(sceneEntity); Assert.AreEqual(3, sectionEntities.Length); Assert.IsTrue(manager.HasComponent <TestMetadata>(sectionEntities[0].SectionEntity)); Assert.IsFalse(manager.HasComponent <TestMetadata>(sectionEntities[1].SectionEntity)); Assert.IsTrue(manager.HasComponent <TestMetadata>(sectionEntities[2].SectionEntity)); Assert.IsTrue(manager.HasComponent <TestMetadataTag>(sectionEntities[0].SectionEntity)); Assert.IsFalse(manager.HasComponent <TestMetadataTag>(sectionEntities[1].SectionEntity)); Assert.IsTrue(manager.HasComponent <TestMetadataTag>(sectionEntities[2].SectionEntity)); // These components should not be added, instead an error is logged that meta info components can't contain entities or blob assets var filteredTypes = new[] { typeof(TestMetadataWithEntity), typeof(TestMetadataWithBlobAsset), typeof(EcsTestSharedComp), typeof(EcsIntElement), typeof(EcsState1), #if !UNITY_DISABLE_MANAGED_COMPONENTS typeof(EcsTestManagedComponent) #endif }; foreach (var type in filteredTypes) { var componentType = ComponentType.FromTypeIndex(TypeManager.GetTypeIndex(type)); Assert.IsFalse(manager.HasComponent(sectionEntities[0].SectionEntity, componentType)); } Assert.AreEqual(0, manager.GetComponentData <TestMetadata>(sectionEntities[0].SectionEntity).SectionIndex); Assert.AreEqual(13, manager.GetComponentData <TestMetadata>(sectionEntities[0].SectionEntity).Value); Assert.AreEqual(42, manager.GetComponentData <TestMetadata>(sectionEntities[2].SectionEntity).SectionIndex); Assert.AreEqual(100, manager.GetComponentData <TestMetadata>(sectionEntities[2].SectionEntity).Value); var hash = EntityScenesPaths.GetSubSceneArtifactHash(SceneGUID, sceneSystem.BuildConfigurationGUID, true, ImportMode.Synchronous); Assert.IsTrue(hash.IsValid); AssetDatabaseCompatibility.GetArtifactPaths(hash, out var paths); var logPath = EntityScenesPaths.GetLoadPathFromArtifactPaths(paths, EntityScenesPaths.PathType.EntitiesConversionLog); Assert.NotNull(logPath); var log = System.IO.File.ReadAllText(logPath); Assert.IsTrue(log.Contains("The component type must contains only blittable/basic data types")); Assert.IsFalse(log.Contains("entities in the scene 'TestSubSceneWithSectionMetadata' had no SceneSection and as a result were not serialized at all.")); } }
bool CheckConversionLog(SubScene subScene) { var pendingWork = false; foreach (var world in World.All) { var sceneSystem = world.GetExistingSystem <SceneSystem>(); if (sceneSystem is null) { continue; } if (!m_ConversionLogLoaded.TryGetValue(sceneSystem.BuildConfigurationGUID, out var loaded)) { m_ConversionLogLoaded.Add(sceneSystem.BuildConfigurationGUID, false); } else if (loaded) { continue; } var hash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, sceneSystem.BuildConfigurationGUID, ImportMode.Asynchronous); if (!hash.IsValid) { pendingWork = true; continue; } m_ConversionLogLoaded[sceneSystem.BuildConfigurationGUID] = true; AssetDatabaseCompatibility.GetArtifactPaths(hash, out var paths); var logPath = EntityScenesPaths.GetLoadPathFromArtifactPaths(paths, EntityScenesPaths.PathType.EntitiesConversionLog); if (logPath == null) { continue; } var log = File.ReadAllText(logPath); if (log.Trim().Length != 0) { if (m_ConversionLog.Length != 0) { m_ConversionLog += "\n\n"; } m_ConversionLog += log; } } return(pendingWork); }
public void SetUpOnce() { #if UNITY_EDITOR try { BuildConfiguration.CreateAsset(m_BuildConfigPath, config => { config.SetComponent(new SceneList { SceneInfos = new List <SceneList.SceneInfo> { new SceneList.SceneInfo { Scene = GlobalObjectId.GetGlobalObjectIdSlow( AssetDatabase.LoadAssetAtPath <SceneAsset>(m_SubScenePath)) } } }); }); m_BuildConfigurationGUID = new GUID(AssetDatabase.AssetPathToGUID(m_BuildConfigPath)); m_SceneGUID = new GUID(AssetDatabase.AssetPathToGUID(m_SubScenePath)); var guid = SceneWithBuildConfigurationGUIDs.EnsureExistsFor(m_SceneGUID, m_BuildConfigurationGUID, true, out var requestRefresh); if (requestRefresh) { AssetDatabase.Refresh(); } m_SceneWithBuildSettingsPath = SceneWithBuildConfigurationGUIDs.GetSceneWithBuildSettingsPath(guid); EntityScenesPaths.GetSubSceneArtifactHash(m_SceneGUID, m_BuildConfigurationGUID, true, ImportMode.Synchronous); } catch { AssetDatabase.DeleteAsset(m_TempPath); AssetDatabase.DeleteAsset(m_SceneWithBuildSettingsPath); throw; } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); #else //TODO: Playmode test not supported yet m_SceneGUID = new Unity.Entities.Hash128(); #endif }
public void SubScene_WithDependencyOnAssetInScene_ClearCache_EndToEnd() { var subScene = SubSceneTestsHelper.CreateSubSceneFromObjects(ref m_TempAssets, "SubScene", false, () => { var go = new GameObject(); var authoring = go.AddComponent <DependencyTestAuthoring>(); var sphereHolder = GameObject.CreatePrimitive(PrimitiveType.Sphere); authoring.Asset = sphereHolder.GetComponent <MeshFilter>().sharedMesh; UnityEngine.Object.DestroyImmediate(sphereHolder); return(new List <GameObject> { go }); }); var buildSettings = default(Unity.Entities.Hash128); var originalHash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.Synchronous); Assert.IsTrue(originalHash.IsValid); // Clear Cache (First time this creates global dependency asset, so we will test both steps) EntitiesCacheUtility.UpdateEntitySceneGlobalDependency(); var newHashCreated = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.Synchronous); Assert.IsTrue(newHashCreated.IsValid); Assert.AreNotEqual(originalHash, newHashCreated); // Clear Cache (This updates existing asset) EntitiesCacheUtility.UpdateEntitySceneGlobalDependency(); var newHashUpdated = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.Synchronous); Assert.IsTrue(newHashUpdated.IsValid); Assert.AreNotEqual(newHashCreated, newHashUpdated); Assert.AreNotEqual(originalHash, newHashUpdated); // Delete created dependency, this cleans up test but also we need to verify that the scene returns to the original hash AssetDatabase.DeleteAsset(EntitiesCacheUtility.globalEntitiesDependencyDir); AssetDatabase.Refresh(); // With the dependency deleted, the hash should return to the original var finalHash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.Synchronous); Assert.AreEqual(originalHash, finalHash); }
public void SubScene_WithDependencyOnAssetInScene_StillImports() { var subScene = SubSceneTestsHelper.CreateSubSceneFromObjects(ref m_TempAssets, "SubScene", false, () => { var go = new GameObject(); var authoring = go.AddComponent <DependencyTestAuthoring>(); var texture = new Texture2D(64, 64); authoring.Asset = texture; return(new List <GameObject> { go }); }); var buildSettings = default(Unity.Entities.Hash128); var hash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.Synchronous); Assert.IsTrue(hash.IsValid); }
public void SubScene_WithDependencyOnBuiltInAsset_StillImports() { var subScene = SubSceneTestsHelper.CreateSubSceneFromObjects(ref m_TempAssets, "SubScene", false, () => { var go = new GameObject(); var authoring = go.AddComponent <DependencyTestAuthoring>(); var sphereHolder = GameObject.CreatePrimitive(PrimitiveType.Sphere); authoring.Asset = sphereHolder.GetComponent <MeshFilter>().sharedMesh; UnityEngine.Object.DestroyImmediate(sphereHolder); return(new List <GameObject> { go }); }); var buildSettings = default(Unity.Entities.Hash128); var hash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, buildSettings, ImportMode.Synchronous); Assert.IsTrue(hash.IsValid); }
static bool IsSubsceneImported(SubScene subScene) { foreach (var world in World.All) { var sceneSystem = world.GetExistingSystem <SceneSystem>(); if (sceneSystem is null) { continue; } var hash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.SceneGUID, sceneSystem.BuildConfigurationGUID, ImportMode.NoImport); if (!hash.IsValid) { return(false); } } return(true); }
//TODO: There is too much code duplication here, refactor this to send general artifacts to the editor unsafe void SendSubScene(Unity.Entities.Hash128 subSceneGuid, Unity.Entities.Hash128 buildSettingsGuid, int playerId) { LiveLinkMsg.LogInfo($"Sending SubScene: 'GUID: {subSceneGuid}' with 'BuildSettings: {buildSettingsGuid}' to playerId: {playerId}"); var hash = EntityScenesPaths.GetSubSceneArtifactHash(subSceneGuid, buildSettingsGuid, AssetDatabaseExperimental.ImportSyncMode.Block); AssetDatabaseExperimental.GetArtifactPaths(hash, out var paths); var sceneHeaderPath = EntityScenesPaths.GetLoadPathFromArtifactPaths(paths, EntityScenesPaths.PathType.EntitiesHeader); if (!File.Exists(sceneHeaderPath)) { Debug.LogError("Send Entity Scene failed because the entity header file could not be found: " + sceneHeaderPath); return; } if (!BlobAssetReference <SceneMetaData> .TryRead(sceneHeaderPath, SceneMetaDataSerializeUtility.CurrentFileFormatVersion, out var sceneMetaDataRef)) { Debug.LogError("Send Entity Scene failed because the entity header file was an old version: " + sceneHeaderPath); return; } ref var sceneMetaData = ref sceneMetaDataRef.Value;
public void RequestSubSceneTargetHash(MessageEventArgs args) { using (var subScenes = args.ReceiveArray <SubSceneGUID>()) { var resolvedScenes = new HashSet <ResolvedSubSceneID>(); foreach (var subScene in subScenes) { LiveLinkMsg.LogInfo($"RequestSubSceneTargetHash => {subScene.Guid}, {subScene.BuildConfigurationGuid}"); var targetHash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.Guid, subScene.BuildConfigurationGuid, UnityEditor.Experimental.AssetDatabaseExperimental.ImportSyncMode.Queue); _UsedSubSceneTargetHash[subScene] = targetHash; if (targetHash.IsValid) { resolvedScenes.Add(new ResolvedSubSceneID { SubSceneGUID = subScene, TargetHash = targetHash }); } } TimeBasedCallbackInvoker.SetCallback(DetectChangedAssets); if (resolvedScenes.Count == 0) { return; } var resolved = new NativeArray <ResolvedSubSceneID>(resolvedScenes.Count, Allocator.Temp); int i = 0; foreach (var id in resolvedScenes) { resolved[i++] = id; } SendSubSceneTargetHash(resolved, args.playerId); } }
public void SubScene_WithDependencyOnAsset_IsInvalidatedWhenAssetChanges() { var subScene = CreateSubScene("SubScene", nameof(SubScene_WithDependencyOnAsset_IsInvalidatedWhenAssetChanges)); SubSceneInspectorUtility.EditScene(subScene); var go = new GameObject(); var authoring = go.AddComponent <DependencyTestAuthoring>(); var dependency = new GameObject(); authoring.GameObject = dependency; var texture = new Texture2D(64, 64); authoring.Asset = texture; var assetPath = Path.Combine(m_TempAssetDir, "Texture.asset"); AssetDatabase.CreateAsset(authoring.Asset, assetPath); SceneManager.MoveGameObjectToScene(dependency, subScene.EditingScene); SceneManager.MoveGameObjectToScene(go, subScene.EditingScene); EditorSceneManager.SaveScene(subScene.EditingScene); AssetDatabase.TryGetGUIDAndLocalFileIdentifier(subScene.SceneAsset, out var guid, out long _); var buildSettings = default(Unity.Entities.Hash128); var subSceneGuid = new GUID(guid); var hash = EntityScenesPaths.GetSubSceneArtifactHash(subSceneGuid, buildSettings, ImportMode.Synchronous); Assert.IsTrue(hash.IsValid); texture.wrapMode = texture.wrapMode == TextureWrapMode.Repeat ? TextureWrapMode.Mirror : TextureWrapMode.Repeat; AssetDatabase.SaveAssets(); var newHash = EntityScenesPaths.GetSubSceneArtifactHash(subSceneGuid, buildSettings, ImportMode.NoImport); Assert.AreNotEqual(hash, newHash); Assert.IsFalse(newHash.IsValid); }
void RequestSubSceneTargetHash(MessageEventArgs args) { //@TODO: should be based on connection / BuildSetting var buildTarget = EditorUserBuildSettings.activeBuildTarget; using (var subScenes = args.ReceiveArray <SubSceneGUID>()) { var resolvedScenes = new HashSet <ResolvedSubSceneID>(); var assetDependencies = new HashSet <ResolvedAssetID>(); foreach (var subScene in subScenes) { LiveLinkMsg.LogInfo($"RequestSubSceneTargetHash => {subScene.Guid}, {subScene.BuildConfigurationGuid}"); var targetHash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.Guid, subScene.BuildConfigurationGuid, ImportMode.Asynchronous); m_TrackedSubScenes[subScene] = targetHash; if (targetHash.IsValid) { resolvedScenes.Add(new ResolvedSubSceneID { SubSceneGUID = subScene, TargetHash = targetHash }); var sceneDependencies = LiveLinkBuildPipeline.GetSubSceneDependencies(targetHash); foreach (var sceneDependency in sceneDependencies) { assetDependencies.Add(sceneDependency); m_TrackedAssets[sceneDependency.GUID] = sceneDependency.TargetHash; if (sceneDependency.TargetHash.IsValid) { LiveLinkBuildPipeline.CalculateTargetDependencies(sceneDependency.TargetHash, buildTarget, out ResolvedAssetID[] dependencies, ImportMode.Asynchronous, sceneDependency.GUID); foreach (var dependency in dependencies) { m_TrackedAssets[dependency.GUID] = dependency.TargetHash; assetDependencies.Add(new ResolvedAssetID { GUID = dependency.GUID, TargetHash = dependency.TargetHash }); } } } } } TimeBasedCallbackInvoker.SetCallback(DetectChangedAssets); if (resolvedScenes.Count == 0) { return; } var resolved = new NativeArray <ResolvedSubSceneID>(resolvedScenes.Count, Allocator.Temp); int i = 0; foreach (var id in resolvedScenes) { resolved[i++] = id; } SendSubSceneTargetHash(resolved, args.playerId); if (assetDependencies.Count > 0) { var resolvedAssets = new NativeArray <ResolvedAssetID>(assetDependencies.Count, Allocator.Temp); int assetIndex = 0; foreach (var asset in assetDependencies) { resolvedAssets[assetIndex++] = asset; } SendAssetTargetHash(resolvedAssets, args.playerId); } } }