public override void OnImportAsset(AssetImportContext ctx) { try { ctx.DependsOnCustomDependency("EntityBinaryFileFormatVersion"); var sceneWithBuildConfiguration = SceneWithBuildConfigurationGUIDs.ReadFromFile(ctx.assetPath); // Ensure we have as many dependencies as possible registered early in case an exception is thrown var scenePath = AssetDatabase.GUIDToAssetPath(sceneWithBuildConfiguration.SceneGUID.ToString()); ctx.DependsOnSourceAsset(scenePath); if (sceneWithBuildConfiguration.BuildConfiguration.IsValid) { var buildConfigurationPath = AssetDatabase.GUIDToAssetPath(sceneWithBuildConfiguration.BuildConfiguration.ToString()); ctx.DependsOnSourceAsset(buildConfigurationPath); var buildConfigurationDependencies = AssetDatabase.GetDependencies(buildConfigurationPath); foreach (var dependency in buildConfigurationDependencies) { ctx.DependsOnSourceAsset(dependency); } } var dependencies = AssetDatabase.GetDependencies(scenePath); foreach (var dependency in dependencies) { if (dependency.ToLower().EndsWith(".prefab")) { ctx.DependsOnSourceAsset(dependency); } } var config = BuildConfiguration.LoadAsset(sceneWithBuildConfiguration.BuildConfiguration); var scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive); try { var settings = new GameObjectConversionSettings(); settings.SceneGUID = sceneWithBuildConfiguration.SceneGUID; settings.BuildConfiguration = config; settings.AssetImportContext = ctx; var sectionRefObjs = new List <ReferencedUnityObjects>(); var sectionData = EditorEntityScenes.ConvertAndWriteEntityScene(scene, settings, sectionRefObjs); WriteRefGuids(sectionRefObjs, sectionData, ctx); } finally { EditorSceneManager.CloseScene(scene, true); } } // Currently it's not acceptable to let the asset database catch the exception since it will create a default asset without any dependencies // This means a reimport will not be triggered if the scene is subsequently modified catch (Exception e) { Debug.Log($"Exception thrown during SubScene import: {e}"); } }
public static void SceneSavingCallback(Scene scene, string scenePath) { var sceneGUID = new GUID(AssetDatabase.AssetPathToGUID(scenePath)); if (EditorEntityScenes.HasEntitySceneCache(sceneGUID)) { EditorEntityScenes.WriteEntityScene(scene, sceneGUID, 0); } }
public override void OnImportAsset(AssetImportContext ctx) { try { var sceneWithBuildSettings = ReadSceneWithBuildSettings(ctx.assetPath); // Ensure we have as many dependencies as possible registered early in case an exception is thrown var scenePath = AssetDatabase.GUIDToAssetPath(sceneWithBuildSettings.SceneGUID.ToString()); ctx.DependsOnSourceAsset(scenePath); if (sceneWithBuildSettings.BuildSettings.IsValid) { var buildSettingPath = AssetDatabase.GUIDToAssetPath(sceneWithBuildSettings.BuildSettings.ToString()); ctx.DependsOnSourceAsset(buildSettingPath); var buildSettingDependencies = AssetDatabase.GetDependencies(buildSettingPath); foreach (var dependency in buildSettingDependencies) { ctx.DependsOnSourceAsset(dependency); } } var dependencies = AssetDatabase.GetDependencies(scenePath); foreach (var dependency in dependencies) { if (dependency.ToLower().EndsWith(".prefab")) { ctx.DependsOnSourceAsset(dependency); } } var buildSettings = BuildSettings.LoadBuildSettings(sceneWithBuildSettings.BuildSettings); var scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive); try { var settings = new GameObjectConversionSettings(); settings.SceneGUID = sceneWithBuildSettings.SceneGUID; settings.BuildSettings = buildSettings; settings.AssetImportContext = ctx; EditorEntityScenes.WriteEntityScene(scene, settings); } finally { EditorSceneManager.CloseScene(scene, true); } } // Currently it's not acceptable to let the asset database catch the exception since it will create a default asset without any dependencies // This means a reimport will not be triggered if the scene is subsequently modified catch (Exception e) { Debug.Log($"Exception thrown during SubScene import: {e.Message}"); } }
static void CreateSubSceneAndMoveObjectInside(Scene parentScene, Transform parent, GameObject[] objects, string name) { EditorSceneManager.MarkSceneDirty(parentScene); var srcPath = parentScene.path; var dstDirectory = Path.Combine(Path.GetDirectoryName(srcPath), Path.GetFileNameWithoutExtension(parentScene.path)); var dstPath = Path.Combine(dstDirectory, name + ".unity"); Directory.CreateDirectory(dstDirectory); var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive); scene.isSubScene = true; foreach (var go in objects) { go.transform.SetParent(null, true); SceneManager.MoveGameObjectToScene(go, scene); } EditorSceneManager.SaveScene(scene, dstPath); var sceneAsset = AssetDatabase.LoadAssetAtPath <SceneAsset>(dstPath); var gameObject = new GameObject(name, typeof(SubScene)); gameObject.SetActive(false); var subScene = gameObject.GetComponent <SubScene>(); subScene.SceneAsset = sceneAsset; if (parent) { gameObject.transform.parent = parent; } else { SceneManager.MoveGameObjectToScene(gameObject, parentScene); } EditorEntityScenes.WriteEntityScene(subScene); gameObject.SetActive(true); Selection.activeObject = gameObject; }
static string GetWarnings(GameObject gameobject) { var isSubScene = EditorEntityScenes.IsEntitySubScene(gameobject.scene); gameobject.GetComponentsInParent(true, s_ConvertToEntityBuffer); var convertToEntity = s_ConvertToEntityBuffer.Count > 0; s_ConvertToEntityBuffer.Clear(); var willBeConverted = convertToEntity | isSubScene; if (!willBeConverted) { Type convertType = null; foreach (var behaviour in gameobject.GetComponents <MonoBehaviour>()) { if (behaviour != null && behaviour.GetType().GetCustomAttribute <RequiresEntityConversionAttribute>(true) != null) { convertType = behaviour.GetType(); break; } } if (convertType != null) { return($"The {convertType.Name} component on '{gameobject.name}' is meant for entity conversion, but it is not part of a SubScene or ConvertToEntity component.\nPlease move the game object to a SubScene or add the ConvertToEntity component."); } } if (isSubScene && convertToEntity) { return($"'{gameobject.name}' will be converted due to being in a SubScene. ConvertToEntity will have no effect.\nPlease remove the ConvertToEntity component."); } if (isSubScene && gameobject.GetComponent <GameObjectEntity>() != null) { return($"'{gameobject.name}' will be converted due to being in a SubScene. GameObjectEntity will have no effect the game object will not be loaded.\nPlease remove the GameObjectEntity component"); } if (convertToEntity && gameobject.GetComponent <GameObjectEntity>() != null) { return($"'{gameobject.name}' will be converted due to being in a ConvertToEntity hierarchy. GameObjectEntity will have no effect.\nPlease remove the GameObjectEntity component."); } return(null); }
public static void RebuildEntityCache(params SubScene[] scenes) { try { Profiler.BeginSample("AssetDatabase.StartAssetEditing"); AssetDatabase.StartAssetEditing(); Profiler.EndSample(); for (int i = 0; i != scenes.Length; i++) { var scene = scenes[i]; EditorUtility.DisplayProgressBar("Rebuilding Entity Cache", scene.SceneName, (float)i / scenes.Length); var isLoaded = scene.IsLoaded; if (!isLoaded) { EditScene(scene); } try { EditorEntityScenes.WriteEntityScene(scene); scene.UpdateSceneEntities(); } catch (Exception exception) { Debug.LogException(exception); } if (!isLoaded) { CloseSceneWithoutSaving(scene); } } } finally { Profiler.BeginSample("AssetDatabase.StopAssetEditing"); AssetDatabase.StopAssetEditing(); Profiler.EndSample(); EditorUtility.ClearProgressBar(); } }
static void AddEntityBinaryFiles(Hash128 buildConfigurationGuid, string[] scenePathsForBuild, EntitySectionBundlesInBuild sectionBundlesInBuild) { var subSceneGuids = scenePathsForBuild.SelectMany(scenePath => EditorEntityScenes.GetSubScenes(AssetDatabaseCompatibility.PathToGUID(scenePath))).Distinct().ToList(); var requiresRefresh = false; var sceneBuildConfigGuids = new NativeArray <GUID>(subSceneGuids.Count, Allocator.TempJob); for (int i = 0; i != sceneBuildConfigGuids.Length; i++) { sceneBuildConfigGuids[i] = SceneWithBuildConfigurationGUIDs.EnsureExistsFor(subSceneGuids[i], buildConfigurationGuid, false, out var thisRequiresRefresh); requiresRefresh |= thisRequiresRefresh; sectionBundlesInBuild.Add(subSceneGuids[i], sceneBuildConfigGuids[i], typeof(SubSceneImporter)); } if (requiresRefresh) { AssetDatabase.Refresh(); } AssetDatabaseCompatibility.ProduceArtifactsAsync(sceneBuildConfigGuids, typeof(SubSceneImporter)); sceneBuildConfigGuids.Dispose(); }
static string GetWarning(GameObject gameObject) { // only care about scene objects if (gameObject == null) { return(null); } // assets have no scene context if (gameObject.IsPrefab()) { return(null); } // editing in a preview scene (like a prefab in isolation mode) also has no context if (EditorSceneManager.IsPreviewSceneObject(gameObject)) { return(null); } var isSubScene = EditorEntityScenes.IsEntitySubScene(gameObject.scene); gameObject.GetComponentsInParent(true, s_ConvertToEntityBuffer); var convertToEntity = s_ConvertToEntityBuffer.Count > 0; s_ConvertToEntityBuffer.Clear(); var willBeConverted = convertToEntity | isSubScene; if (!willBeConverted) { Type convertType = null; foreach (var behaviour in gameObject.GetComponents <MonoBehaviour>()) { if (behaviour != null && behaviour.GetType().GetCustomAttribute <RequiresEntityConversionAttribute>(true) != null) { convertType = behaviour.GetType(); break; } } if (convertType != null) { return ($"The {convertType.Name} component on '{gameObject.name}' is meant for entity conversion, " + $"but it is not part of a {nameof(SubScene)} or {nameof(ConvertToEntity)} component.\n" + $"Please move the {nameof(GameObject)} to a {nameof(SubScene)} or add the {nameof(ConvertToEntity)} component."); } } if (isSubScene && convertToEntity) { return ($"'{gameObject.name}' will be converted due to being in a {nameof(SubScene)}. {nameof(ConvertToEntity)} " + $"will have no effect. Please remove the {nameof(ConvertToEntity)} component."); } if (isSubScene && gameObject.GetComponent <GameObjectEntity>() != null) { return ($"'{gameObject.name}' will be converted due to being in a {nameof(SubScene)}. {nameof(GameObjectEntity)} " + $"will have no effect the {nameof(GameObject)} will not be loaded.\nPlease remove the {nameof(GameObjectEntity)} component"); } if (convertToEntity && gameObject.GetComponent <GameObjectEntity>() != null) { return ($"'{gameObject.name}' will be converted due to being in a {nameof(ConvertToEntity)} hierarchy. " + $"{nameof(GameObjectEntity)} will have no effect.\nPlease remove the {nameof(GameObjectEntity)} component."); } return(null); }
public override void OnImportAsset(AssetImportContext ctx) { try { ctx.DependsOnCustomDependency("EntityBinaryFileFormatVersion"); ctx.DependsOnCustomDependency("SceneMetaDataFileFormatVersion"); ctx.DependsOnSourceAsset(EntitiesCacheUtility.globalEntitySceneDependencyPath); var sceneWithBuildConfiguration = SceneWithBuildConfigurationGUIDs.ReadFromFile(ctx.assetPath); // Ensure we have as many dependencies as possible registered early in case an exception is thrown var scenePath = AssetDatabase.GUIDToAssetPath(sceneWithBuildConfiguration.SceneGUID.ToString()); ctx.DependsOnSourceAsset(scenePath); if (sceneWithBuildConfiguration.BuildConfiguration.IsValid) { var buildConfigurationPath = AssetDatabase.GUIDToAssetPath(sceneWithBuildConfiguration.BuildConfiguration.ToString()); ctx.DependsOnSourceAsset(buildConfigurationPath); var buildConfigurationDependencies = AssetDatabase.GetDependencies(buildConfigurationPath); foreach (var dependency in buildConfigurationDependencies) { ctx.DependsOnSourceAsset(dependency); } } var dependencies = AssetDatabase.GetDependencies(scenePath); foreach (var dependency in dependencies) { if (dependency.ToLower().EndsWith(".prefab")) { ctx.DependsOnSourceAsset(dependency); } } var config = BuildConfiguration.LoadAsset(sceneWithBuildConfiguration.BuildConfiguration); var scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive); try { var settings = new GameObjectConversionSettings(); settings.SceneGUID = sceneWithBuildConfiguration.SceneGUID; settings.BuildConfiguration = config; settings.AssetImportContext = ctx; settings.FilterFlags = WorldSystemFilterFlags.HybridGameObjectConversion; WriteEntitySceneSettings writeEntitySettings = new WriteEntitySceneSettings(); if (config != null && config.TryGetComponent <DotsRuntimeBuildProfile>(out var profile)) { if (config.TryGetComponent <DotsRuntimeRootAssembly>(out var rootAssembly)) { ctx.DependsOnSourceAsset(AssetDatabase.GetAssetPath(rootAssembly.RootAssembly.asset)); EditorSceneManager.SetActiveScene(scene); writeEntitySettings.Codec = Codec.LZ4; writeEntitySettings.IsDotsRuntime = true; writeEntitySettings.BuildAssemblyCache = new BuildAssemblyCache() { BaseAssemblies = rootAssembly.RootAssembly.asset, PlatformName = profile.Target.UnityPlatformName }; settings.FilterFlags = WorldSystemFilterFlags.DotsRuntimeGameObjectConversion; } } var sectionRefObjs = new List <ReferencedUnityObjects>(); var sectionData = EditorEntityScenes.ConvertAndWriteEntitySceneInternal(scene, settings, sectionRefObjs, writeEntitySettings); WriteAssetDependencyGUIDs(sectionRefObjs, sectionData, ctx); } finally { EditorSceneManager.CloseScene(scene, true); } } // Currently it's not acceptable to let the asset database catch the exception since it will create a default asset without any dependencies // This means a reimport will not be triggered if the scene is subsequently modified catch (Exception e) { Debug.Log($"Exception thrown during SubScene import: {e}"); } }
public override void OnImportAsset(AssetImportContext ctx) { try { var sceneWithBuildConfiguration = SceneWithBuildConfigurationGUIDs.ReadFromFile(ctx.assetPath); // Ensure we have as many dependencies as possible registered early in case an exception is thrown EditorEntityScenes.AddEntityBinaryFileDependencies(ctx, sceneWithBuildConfiguration.BuildConfiguration); EditorEntityScenes.DependOnSceneGameObjects(sceneWithBuildConfiguration.SceneGUID, ctx); var config = BuildConfiguration.LoadAsset(sceneWithBuildConfiguration.BuildConfiguration); var scenePath = AssetDatabaseCompatibility.GuidToPath(sceneWithBuildConfiguration.SceneGUID); var scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive); try { EditorSceneManager.SetActiveScene(scene); var settings = new GameObjectConversionSettings(); settings.SceneGUID = sceneWithBuildConfiguration.SceneGUID; if (!sceneWithBuildConfiguration.IsBuildingForEditor) { settings.ConversionFlags |= GameObjectConversionUtility.ConversionFlags.IsBuildingForPlayer; } settings.BuildConfiguration = config; settings.AssetImportContext = ctx; settings.FilterFlags = WorldSystemFilterFlags.HybridGameObjectConversion; WriteEntitySceneSettings writeEntitySettings = new WriteEntitySceneSettings(); if (config != null && config.TryGetComponent <DotsRuntimeBuildProfile>(out var profile)) { if (config.TryGetComponent <DotsRuntimeRootAssembly>(out var rootAssembly)) { writeEntitySettings.Codec = Codec.LZ4; writeEntitySettings.IsDotsRuntime = true; writeEntitySettings.BuildAssemblyCache = new BuildAssemblyCache() { BaseAssemblies = rootAssembly.RootAssembly.asset, PlatformName = profile.Target.UnityPlatformName }; settings.FilterFlags = WorldSystemFilterFlags.DotsRuntimeGameObjectConversion; //Updating the root asmdef references or its references should re-trigger conversion ctx.DependsOnArtifact(AssetDatabase.GetAssetPath(rootAssembly.RootAssembly.asset)); foreach (var assemblyPath in writeEntitySettings.BuildAssemblyCache.AssembliesPath) { ctx.DependsOnArtifact(assemblyPath); } } } var sectionRefObjs = new List <ReferencedUnityObjects>(); var sectionData = EditorEntityScenes.ConvertAndWriteEntityScene(scene, settings, sectionRefObjs, writeEntitySettings); WriteAssetDependencyGUIDs(sectionRefObjs, sectionData, ctx); foreach (var objRefs in sectionRefObjs) { DestroyImmediate(objRefs); } } finally { EditorSceneManager.CloseScene(scene, true); } } // Currently it's not acceptable to let the asset database catch the exception since it will create a default asset without any dependencies // This means a reimport will not be triggered if the scene is subsequently modified catch (Exception e) { Debug.Log($"Exception thrown during SubScene import: {e}"); } }