protected override void OnUpdate() { Entities.WithNone <EditorCompanionInPreviewSceneTag>().ForEach((EditorRenderData renderData, CompanionLink link) => { foreach (var sceneAndMask in m_CompanionScenes) { if (sceneAndMask.mask == renderData.SceneCullingMask) { EditorSceneManager.MoveGameObjectToScene(link.Companion, sceneAndMask.scene); return; } } var scene = EditorSceneManager.NewPreviewScene(); m_CompanionScenes.Add(new SceneAndMask { scene = scene, mask = renderData.SceneCullingMask }); EditorSceneManager.SetSceneCullingMask(scene, renderData.SceneCullingMask); EditorSceneManager.MoveGameObjectToScene(link.Companion, scene); }); EntityManager.AddComponent <EditorCompanionInPreviewSceneTag>(m_WithoutTag); }
//Called when MainWindow is opened public void CreateScene() { //Scene scene = EditorSceneManager.NewPreviewScene(); scene.name = "Noise Perspective"; //Culling mask ulong cullingMask = EditorSceneManager.CalculateAvailableSceneCullingMask(); EditorSceneManager.SetSceneCullingMask(scene, cullingMask); //Prevents running out of culling masks if editor is reopened several times //Light GameObject lightGo = new GameObject(); sceneLight = lightGo.AddComponent <Light>(); sceneLight.type = LightType.Directional; EditorSceneManager.MoveGameObjectToScene(lightGo, scene); lightGo.transform.position = lightGo.transform.up * 10; lightGo.transform.rotation = Quaternion.Euler(60, 0, 0); sceneLight.shadows = LightShadows.None; }
protected override void OnUpdate() { // We can't initialize live link in OnCreate because other systems might configure BuildConfigurationGUID from OnCreate if (_EditorLiveLink == null) { _EditorLiveLink = new LiveLinkConnection(World.GetExistingSystem <SceneSystem>().BuildConfigurationGUID); } try { if (_SceneChangeTracker.GetSceneMessage(out var msg)) { _EditorLiveLink.ApplyLiveLinkSceneMsg(msg); msg.Dispose(); } _EditorLiveLink.Update(_ChangeSets, _LoadScenes, _UnloadScenes, SubSceneInspectorUtility.LiveLinkMode); // Unload scenes that are no longer being edited / need to be reloaded etc foreach (var change in _UnloadScenes) { _Patcher.UnloadScene(change); } // Apply changes to scenes that are being edited foreach (var change in _ChangeSets) { _Patcher.ApplyPatch(change); change.Dispose(); } } finally { _LoadScenes.Clear(); _ChangeSets.Clear(); _UnloadScenes.Clear(); } if (_EditorLiveLink.HasLoadedScenes()) { // Configure scene culling masks so that game objects & entities are rendered exlusively to each other var liveLinkEnabled = SubSceneInspectorUtility.LiveLinkMode != LiveLinkMode.Disabled; for (int i = 0; i != EditorSceneManager.sceneCount; i++) { var scene = EditorSceneManager.GetSceneAt(i); // TODO: Generates garbage, need better API var sceneGUID = new GUID(AssetDatabase.AssetPathToGUID(scene.path)); if (_EditorLiveLink.HasScene(sceneGUID)) { #if UNITY_2020_1_OR_NEWER if (SubSceneInspectorUtility.LiveLinkMode == LiveLinkMode.LiveConvertGameView) { EditorSceneManager.SetSceneCullingMask(scene, SceneCullingMasks.MainStageSceneViewObjects); } else if (SubSceneInspectorUtility.LiveLinkMode == LiveLinkMode.LiveConvertSceneView) { EditorSceneManager.SetSceneCullingMask(scene, m_GizmoSceneCullingMask); } else { EditorSceneManager.SetSceneCullingMask(scene, EditorSceneManager.DefaultSceneCullingMask); } #else if (liveLinkEnabled) { EditorSceneManager.SetSceneCullingMask(scene, EditorRenderData.LiveLinkEditSceneViewMask); } else { EditorSceneManager.SetSceneCullingMask(scene, EditorSceneManager.DefaultSceneCullingMask | EditorRenderData.LiveLinkEditGameViewMask); } #endif } } } }
protected override void OnUpdate() { List <SubScene> needLiveLinkSync = null; List <SubScene> cleanupScene = null; List <SubScene> markSceneLoadedFromLiveLink = null; List <SubScene> removeSceneLoadedFromLiveLink = null; m_EditingSceneAssets.Clear(); var liveLinkEnabled = SubSceneInspectorUtility.LiveLinkEnabled; // By default all scenes need to have m_GameObjectSceneCullingMask, otherwise they won't show up in game view for (int i = 0; i != EditorSceneManager.sceneCount; i++) { var scene = EditorSceneManager.GetSceneAt(i); if (scene.isSubScene) { if (liveLinkEnabled) { EditorSceneManager.SetSceneCullingMask(scene, m_LiveLinkEditSceneViewMask); } else { EditorSceneManager.SetSceneCullingMask(scene, EditorSceneManager.DefaultSceneCullingMask | m_LiveLinkEditGameViewMask); } var sceneAsset = AssetDatabase.LoadAssetAtPath <SceneAsset>(scene.path); if (scene.isLoaded && sceneAsset != null) { m_EditingSceneAssets.Add(sceneAsset); } } } if (PreviousGlobalDirtyID != GlobalDirtyID) { Entities.ForEach((SubScene subScene) => { subScene.LiveLinkDirtyID = -1; }); PreviousGlobalDirtyID = GlobalDirtyID; } Entities.ForEach((SubScene subScene) => { var isLoaded = m_EditingSceneAssets.Contains(subScene.SceneAsset); // We are editing with live link. Ensure it is active & up to date if (isLoaded && liveLinkEnabled) { if (subScene.LiveLinkDirtyID != GetSceneDirtyID(subScene.LoadedScene) || subScene.LiveLinkShadowWorld == null) { AddUnique(ref needLiveLinkSync, subScene); } } // We are editing without live link. // We should have no entity representation loaded for the scene. else if (isLoaded && !liveLinkEnabled) { var hasAnythingLoaded = false; foreach (var s in subScene._SceneEntities) { hasAnythingLoaded |= EntityManager.HasComponent <SubSceneStreamingSystem.StreamingState>(s) || !EntityManager.HasComponent <SubSceneStreamingSystem.IgnoreTag>(s); } if (hasAnythingLoaded) { AddUnique(ref cleanupScene, subScene); AddUnique(ref markSceneLoadedFromLiveLink, subScene); } } // Scene is not being edited, thus should not be live linked. else { var isDrivenByLiveLink = false; foreach (var s in subScene._SceneEntities) { isDrivenByLiveLink |= EntityManager.HasComponent <SubSceneStreamingSystem.IgnoreTag>(s); } if (isDrivenByLiveLink || subScene.LiveLinkShadowWorld != null) { AddUnique(ref cleanupScene, subScene); AddUnique(ref removeSceneLoadedFromLiveLink, subScene); } } }); if (needLiveLinkSync != null) { // Live link changes to entity world foreach (var scene in needLiveLinkSync) { // Prevent live link updating during drag operation // (Currently performance is not good enough to do it completely live) if (!IsHotControlActive()) { ApplyLiveLink(scene); } else { EditorUpdateUtility.EditModeQueuePlayerLoopUpdate(); } } } if (cleanupScene != null) { // Live link changes to entity world foreach (var scene in cleanupScene) { CleanupScene(scene); } } if (markSceneLoadedFromLiveLink != null) { foreach (var scene in markSceneLoadedFromLiveLink) { foreach (var sceneEntity in scene._SceneEntities) { if (!EntityManager.HasComponent <SubSceneStreamingSystem.IgnoreTag>(sceneEntity)) { EntityManager.AddComponentData(sceneEntity, new SubSceneStreamingSystem.IgnoreTag()); } } } } if (removeSceneLoadedFromLiveLink != null) { foreach (var scene in removeSceneLoadedFromLiveLink) { foreach (var sceneEntity in scene._SceneEntities) { EntityManager.RemoveComponent <SubSceneStreamingSystem.IgnoreTag>(sceneEntity); } } } }
protected override void OnUpdate() { List <SubScene> needLiveLinkSync = null; List <SubScene> cleanupScene = null; List <SubScene> markSceneLoadedFromLiveLink = null; List <SubScene> removeSceneLoadedFromLiveLink = null; m_EditingSceneAssets.Clear(); var liveLinkEnabled = SubSceneInspectorUtility.LiveLinkMode != LiveLinkMode.Disabled; // By default all scenes need to have m_GameObjectSceneCullingMask, otherwise they won't show up in game view for (int i = 0; i != EditorSceneManager.sceneCount; i++) { var scene = EditorSceneManager.GetSceneAt(i); if (scene.isSubScene) { if (liveLinkEnabled) { EditorSceneManager.SetSceneCullingMask(scene, EditorRenderData.LiveLinkEditSceneViewMask); } else { EditorSceneManager.SetSceneCullingMask(scene, EditorSceneManager.DefaultSceneCullingMask | EditorRenderData.LiveLinkEditGameViewMask); } var sceneAsset = AssetDatabase.LoadAssetAtPath <SceneAsset>(scene.path); if (scene.isLoaded && sceneAsset != null) { m_EditingSceneAssets.Add(sceneAsset); } } } if (PreviousGlobalDirtyID != GlobalDirtyID) { Entities.ForEach((SubScene subScene) => { if (subScene.LiveLinkData != null) { subScene.LiveLinkData.RequestCleanConversion(); } }); PreviousGlobalDirtyID = GlobalDirtyID; } Entities.ForEach((SubScene subScene) => { var isLoaded = m_EditingSceneAssets.Contains(subScene.SceneAsset); // We are editing with live link. Ensure it is active & up to date if (isLoaded && liveLinkEnabled) { if (subScene.LiveLinkData == null) { AddUnique(ref needLiveLinkSync, subScene); } else { if (subScene.LiveLinkData.LiveLinkDirtyID != GetSceneDirtyID(subScene.LoadedScene) || subScene.LiveLinkData.DidRequestUpdate()) { AddUnique(ref needLiveLinkSync, subScene); } } } // We are editing without live link. // We should have no entity representation loaded for the scene. else if (isLoaded && !liveLinkEnabled) { var hasAnythingLoaded = false; foreach (var s in subScene._SceneEntities) { hasAnythingLoaded |= EntityManager.HasComponent <SubSceneStreamingSystem.StreamingState>(s) || !EntityManager.HasComponent <SubSceneStreamingSystem.IgnoreTag>(s); } if (hasAnythingLoaded) { AddUnique(ref cleanupScene, subScene); AddUnique(ref markSceneLoadedFromLiveLink, subScene); } } // Scene is not being edited, thus should not be live linked. else { var isDrivenByLiveLink = false; foreach (var s in subScene._SceneEntities) { isDrivenByLiveLink |= EntityManager.HasComponent <SubSceneStreamingSystem.IgnoreTag>(s); } if (isDrivenByLiveLink || subScene.LiveLinkData != null) { AddUnique(ref cleanupScene, subScene); AddUnique(ref removeSceneLoadedFromLiveLink, subScene); } } }); if (needLiveLinkSync != null) { var shouldDelayLiveLink = SubSceneInspectorUtility.LiveLinkMode == LiveLinkMode.ConvertWithoutDiff; // Live link changes to entity world foreach (var scene in needLiveLinkSync) { if (shouldDelayLiveLink) { EditorUpdateUtility.EditModeQueuePlayerLoopUpdate(); } else { // The current behaviour is that we do incremental conversion until we release the hot control // This is to avoid any unexpected stalls // Optimally the undo system would tell us if only properties have changed, but currently we don't have such an event stream. var sceneDirtyID = GetSceneDirtyID(scene.LoadedScene); if (IsHotControlActive()) { if (scene.LiveLinkData != null) { LiveLinkScene.ApplyLiveLink(scene, World, scene.LiveLinkData.LiveLinkDirtyID, SubSceneInspectorUtility.LiveLinkMode); } else { EditorUpdateUtility.EditModeQueuePlayerLoopUpdate(); } } else { if (scene.LiveLinkData != null && scene.LiveLinkData.LiveLinkDirtyID != sceneDirtyID) { scene.LiveLinkData.RequestCleanConversion(); } LiveLinkScene.ApplyLiveLink(scene, World, sceneDirtyID, SubSceneInspectorUtility.LiveLinkMode); } } } } if (cleanupScene != null) { // Live link changes to entity world foreach (var scene in cleanupScene) { CleanupScene(scene); } } if (markSceneLoadedFromLiveLink != null) { foreach (var scene in markSceneLoadedFromLiveLink) { foreach (var sceneEntity in scene._SceneEntities) { if (!EntityManager.HasComponent <SubSceneStreamingSystem.IgnoreTag>(sceneEntity)) { EntityManager.AddComponentData(sceneEntity, new SubSceneStreamingSystem.IgnoreTag()); } } } } if (removeSceneLoadedFromLiveLink != null) { foreach (var scene in removeSceneLoadedFromLiveLink) { foreach (var sceneEntity in scene._SceneEntities) { EntityManager.RemoveComponent <SubSceneStreamingSystem.IgnoreTag>(sceneEntity); } } } }
void RenderRows(WindowData windowData) { // todo show spinner until scene is loaded, if (FileResultRows.GetEntitiesCount() > 0) { windowData.ExpandFiles = EditorGUILayout.Foldout(windowData.ExpandFiles, $"Usages in Project: {FileResultRows.GetEntitiesCount()}"); } if (SearchArgMain.IsEmpty()) { return; } if (windowData.ExpandFiles && windowData.FindFrom == FindModeEnum.File) { foreach (var i in FileResultRows.Out(out var get1, out var get2, out _, out _)) { DrawRowFile(get1[i], get2[i], windowData); } } var sceneMessage = $"Usages in Scenes: {ScenePaths.GetEntitiesCount()}"; if (ScenePaths.GetEntitiesCount() > 0) { windowData.ExpandScenes = EditorGUILayout.Foldout(windowData.ExpandScenes, sceneMessage); } if (!windowData.ExpandScenes) { return; } if (windowData.ExpandScenes && windowData.FindFrom == FindModeEnum.Scene) { foreach (var(grp, indices) in SceneResultRows.Out(out _, out var get2, out _, out _) .GroupBy1(ResultComp.Instance)) { using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { var count = 0; foreach (var i in indices) { if (count++ == 0) { if (GUILayout.Button(get2[i].Label, windowData.Style.RowMainAssetBtn)) { if (windowData.Click.IsDoubleClick(grp.RootGo)) { // _selectionChangedByArrows = false; Selection.activeObject = grp.RootGo; } else { EditorGUIUtility.PingObject(grp.RootGo); } windowData.Click = new PrevClick(grp.RootGo); } } DrawRowScene(get2[i]); } } } } using (new GUILayout.HorizontalScope()) { GUILayout.Space(windowData.Style.SceneIndent1); using (new EditorGUILayout.VerticalScope()) { foreach (var i1 in ScenePaths.Out(out var get1, out var get2, out _)) { windowData.SceneFoldout.text = get1[i1].PathNicified; var details = get2[i1]; details.SearchRequested = details.Scene.isLoaded; details.SearchRequested = EditorGUILayout.Foldout(details.SearchRequested, windowData.SceneFoldout, EditorStyles.foldout); if (details.SearchRequested && details.Scene.isLoaded && !details.SearchDone) { var mainArg = SearchArgMain.GetSingle(); mainArg.Scene = SceneManager.GetSceneByPath(details.Scene.path); SearchUtils.InScene(mainArg, details.Scene); details.SearchDone = true; } if (!details.SearchRequested) { if (!details.Scene.isLoaded) { continue; } if (!details.WasOpened) { // to clean up on selection change AufCtx.World.NewEntityWith(out SceneToClose comp); comp.Scene = details.Scene; comp.ForceClose = true; } foreach (var row in SceneResultRows.Out(out _, out _, out var get3, out var entities)) { if (!get3[row].ScenePath.Eq(details.Path)) { continue; } entities[row].Destroy(); } details.SearchDone = false; } else { if (!details.Scene.isLoaded) { details.Scene = EditorSceneManager.OpenScene(details.Path, OpenSceneMode.Additive); // to clean up on selection change AufCtx.World.NewEntityWith(out SceneToClose comp); comp.Scene = details.Scene; comp.SelectionId = Globals <PersistentUndoRedoState> .Value.Id; #if UNITY_2019_1_OR_NEWER EditorSceneManager.SetSceneCullingMask(details.Scene, 0); #endif details.SearchRequested = true; // todo Scope component #if later if (details.Scene.isLoaded) { EditorSceneManager.CloseScene(details.Scene, false); } #endif } else if (SceneResultRows.IsEmpty()) { EditorGUILayout.LabelField("No in-scene dependencies found."); } else { using (new GUILayout.HorizontalScope()) { GUILayout.Space(windowData.Style.SceneIndent2); using (new EditorGUILayout.VerticalScope()) foreach (var(grp, indices) in SceneResultRows .Out(out var g1, out var g2, out var g3, out _) .GroupBy1(ResultComp.Instance)) { var any = false; foreach (var i3 in indices) { if (!g3[i3].ScenePath.Eq(details.Path)) { continue; } any = true; break; } if (!any) { continue; } using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { var count = 0; foreach (var i2 in indices) { if (!g3[i2].ScenePath.Eq(details.Path)) { continue; } if (count++ == 0) { Result comp = g1[i2]; if (GUILayout.Button(g2[i2].Label, windowData.Style.RowMainAssetBtn)) { if (windowData.Click.IsDoubleClick(grp.RootGo)) { // _selectionChangedByArrows = false; Selection.activeObject = comp.RootGo; } else { EditorGUIUtility.PingObject(comp.RootGo); } windowData.Click = new PrevClick(comp.RootGo); } } DrawRowScene(g2[i2]); } } } } } } } } } }