Sfoglia il codice sorgente

Feature: Editor now loads scenes asynchronously

BearishSun 7 anni fa
parent
commit
31e5dbe79a

+ 34 - 2
Source/Scripting/MBansheeEditor/General/EditorApplication.cs

@@ -166,6 +166,34 @@ namespace BansheeEditor
             get { return Internal_HasFocus(); }
         }
 
+        /// <summary>
+        /// Returns true if the editor is waiting on a scene to be asynchronously loaded.
+        /// </summary>
+        public static bool IsSceneLoading
+        {
+            get
+            {
+                if (lastLoadedScene != null)
+                    return !lastLoadedScene.IsLoaded;
+
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// Returns the load progress of the scene that's being asynchronously loaded
+        /// </summary>
+        public static float SceneLoadProgress
+        {
+            get
+            {
+                if (lastLoadedScene != null)
+                    return Resources.GetLoadProgress(lastLoadedScene);
+
+                return 0.0f;
+            }
+        }
+
         /// <summary>
         /// Render target that the main camera in the scene (if any) will render its view to. This generally means the main 
         /// game window when running standalone, or the Game viewport when running in editor.
@@ -249,6 +277,7 @@ namespace BansheeEditor
 
         private static FolderMonitor monitor;
         private static ScriptCodeManager codeManager;
+        private static RRef<Prefab> lastLoadedScene;
         private static bool sceneDirty;
         private static bool unitTestsExecuted;
         private static EditorPersistentData persistentData;
@@ -494,9 +523,12 @@ namespace BansheeEditor
                 (scenePath) =>
                 {
                     if (string.IsNullOrEmpty(path))
+                    {
                         Scene.Clear();
+                        lastLoadedScene = null;
+                    }
                     else
-                        Scene.Load(path);
+                        lastLoadedScene = Scene.LoadAsync(path);
 
                     SetSceneDirty(false);
 
@@ -981,7 +1013,7 @@ namespace BansheeEditor
 
             if (!string.IsNullOrWhiteSpace(ProjectSettings.LastOpenScene))
             {
-                Scene.Load(ProjectSettings.LastOpenScene);
+                lastLoadedScene = Scene.LoadAsync(ProjectSettings.LastOpenScene);
                 SetSceneDirty(false);
             }
         }

+ 57 - 3
Source/Scripting/MBansheeEditor/Windows/HierarchyWindow.cs

@@ -13,8 +13,15 @@ namespace BansheeEditor
     /// </summary>
     public class HierarchyWindow : EditorWindow, IGlobalShortcuts
     {
+        private GUIScrollArea treeScrollArea;
         private GUISceneTreeView treeView;
 
+        private GUILayout progressLayout;
+        private GUIProgressBar loadProgressBar;
+        private GUILabel loadLabel;
+
+        private bool loadingProgressShown = false;
+
         /// <summary>
         /// Opens the hierarchy window.
         /// </summary>
@@ -68,17 +75,38 @@ namespace BansheeEditor
 
         private void OnInitialize()
         {
-            GUIScrollArea scrollArea = new GUIScrollArea();
-            GUI.AddElement(scrollArea);
+            treeScrollArea = new GUIScrollArea();
+            GUI.AddElement(treeScrollArea);
 
             treeView = new GUISceneTreeView(GUIOption.FlexibleHeight(20), GUIOption.FlexibleWidth(20));
-            scrollArea.Layout.AddElement(treeView);
+            treeScrollArea.Layout.AddElement(treeView);
+
+            // Loading progress
+            loadLabel = new GUILabel(new LocEdString("Loading scene..."));
+            loadProgressBar = new GUIProgressBar();
+
+            progressLayout = GUI.AddLayoutY();
+            progressLayout.AddFlexibleSpace();
+            GUILayout loadLabelLayout = progressLayout.AddLayoutX();
+            loadLabelLayout.AddFlexibleSpace();
+            loadLabelLayout.AddElement(loadLabel);
+            loadLabelLayout.AddFlexibleSpace();
+
+            GUILayout progressBarLayout = progressLayout.AddLayoutX();
+            progressBarLayout.AddFlexibleSpace();
+            progressBarLayout.AddElement(loadProgressBar);
+            progressBarLayout.AddFlexibleSpace();
+            progressLayout.AddFlexibleSpace();
+
+            progressLayout.Active = false;
 
             EditorVirtualInput.OnButtonUp += OnButtonUp;
         }
 
         private void OnEditorUpdate()
         {
+            UpdateLoadingProgress();
+
             treeView.Update();
         }
 
@@ -87,6 +115,32 @@ namespace BansheeEditor
             EditorVirtualInput.OnButtonUp -= OnButtonUp;
         }
 
+        /// <summary>
+        /// Checks if the load progress bar needs to be shown, shows/hides it and updates the progress accordingly.
+        /// </summary>
+        private void UpdateLoadingProgress()
+        {
+            bool needsProgress = EditorApplication.IsSceneLoading;
+
+            if (needsProgress && !loadingProgressShown)
+            {
+                progressLayout.Active = true;
+                treeScrollArea.Active = false;
+
+                loadingProgressShown = true;
+            }
+            else if(!needsProgress && loadingProgressShown)
+            {
+                progressLayout.Active = false;
+                treeScrollArea.Active = true;
+
+                loadingProgressShown = false;
+            }
+
+            if (needsProgress)
+                loadProgressBar.Percent = EditorApplication.SceneLoadProgress;
+        }
+
         /// <summary>
         /// Triggered when the user presses a virtual button.
         /// </summary>

+ 84 - 11
Source/Scripting/MBansheeEditor/Windows/Scene/SceneWindow.cs

@@ -35,6 +35,7 @@ namespace BansheeEditor
         private RenderTexture renderTexture;
         private GUILayoutY mainLayout;
         private GUIPanel rtPanel;
+        private GUIPanel sceneAxesPanel;
         private GUIButton focusCatcher;
 
         private GUIRenderTexture renderTextureGUI;
@@ -62,11 +63,18 @@ namespace BansheeEditor
 
         private GUIButton cameraOptionsButton;
 
+        private GUILayout progressLayout;
+        private GUIProgressBar loadProgressBar;
+        private GUILabel loadLabel;
+
         private SceneAxesGUI sceneAxesGUI;
 
         private bool hasContentFocus = false;
         private bool HasContentFocus { get { return HasFocus && hasContentFocus; } }
 
+        private bool loadingProgressShown = false;
+        private bool AllowViewportInput { get { return !loadingProgressShown; } }
+
         private int editorSettingsHash = int.MaxValue;
 
         private VirtualButton frameKey;
@@ -315,13 +323,33 @@ namespace BansheeEditor
             handlesLayout.AddElement(rotateSnapInput);
             handlesLayout.AddSpace(10);
             handlesLayout.AddElement(cameraOptionsButton);
+            handlesLayout.SetHeight(viewButton.Bounds.height);
 
             GUIPanel mainPanel = mainLayout.AddPanel();
             rtPanel = mainPanel.AddPanel();
 
+            // Loading progress
+            loadLabel = new GUILabel(new LocEdString("Loading scene..."));
+            loadProgressBar = new GUIProgressBar("", GUIOption.FixedWidth(200));
+
+            progressLayout = mainPanel.AddLayoutY();
+            progressLayout.AddFlexibleSpace();
+            GUILayout loadLabelLayout = progressLayout.AddLayoutX();
+            loadLabelLayout.AddFlexibleSpace();
+            loadLabelLayout.AddElement(loadLabel);
+            loadLabelLayout.AddFlexibleSpace();
+
+            GUILayout progressBarLayout = progressLayout.AddLayoutX();
+            progressBarLayout.AddFlexibleSpace();
+            progressBarLayout.AddElement(loadProgressBar);
+            progressBarLayout.AddFlexibleSpace();
+            progressLayout.AddFlexibleSpace();
+
+            progressLayout.Active = false;
+
             selectionPanel = mainPanel.AddPanel(-1);
 
-            GUIPanel sceneAxesPanel = mainPanel.AddPanel(-1);
+            sceneAxesPanel = mainPanel.AddPanel(-1);
             sceneAxesGUI = new SceneAxesGUI(this, sceneAxesPanel, HandleAxesGUISize, HandleAxesGUISize, ProjectionType.Perspective);
 
             focusCatcher = new GUIButton("", EditorStyles.Blank);
@@ -338,6 +366,7 @@ namespace BansheeEditor
             frameKey = new VirtualButton(FrameBinding);
 
             UpdateRenderTexture(Width, Height - HeaderHeight);
+            UpdateLoadingProgress();
         }
 
         private void OnCameraOptionsClicked()
@@ -522,6 +551,8 @@ namespace BansheeEditor
 
         private void OnEditorUpdate()
         {
+            UpdateLoadingProgress();
+
             if (HasFocus)
             {
                 if (!Input.IsPointerButtonHeld(PointerButton.Right))
@@ -555,8 +586,23 @@ namespace BansheeEditor
 
             Vector2I scenePos;
             bool inBounds = ScreenToScenePos(Input.PointerPosition, out scenePos);
+
+            bool clearSelection = false;
+            if (AllowViewportInput)
+            {
+                if (Input.IsPointerButtonUp(PointerButton.Left))
+                    clearSelection = true;
+                else if (Input.IsPointerButtonDown(PointerButton.Left))
+                    mouseDownPosition = scenePos;
+            }
+            else
+            {
+                clearSelection = true;
+                inBounds = false;
+            }
+
             bool dragResult = false;
-            if (Input.IsPointerButtonUp(PointerButton.Left))
+            if (clearSelection)
             {
                 dragResult = EndDragSelection();
                 if (sceneHandles.IsActive())
@@ -565,10 +611,6 @@ namespace BansheeEditor
                 if (sceneAxesGUI.IsActive())
                     sceneAxesGUI.ClearSelection();
             }
-            else if (Input.IsPointerButtonDown(PointerButton.Left))
-            {
-                mouseDownPosition = scenePos;
-            }
 
             bool draggedOver = DragDrop.DragInProgress || DragDrop.DropInProgress;
             draggedOver &= IsPointerHovering && inBounds && DragDrop.Type == DragDropType.Resource;
@@ -676,7 +718,7 @@ namespace BansheeEditor
                 }
             }
 
-            if (HasContentFocus || IsPointerHovering)
+            if ((HasContentFocus || IsPointerHovering) && AllowViewportInput)
             {
                 cameraController.EnableInput(true);
 
@@ -715,10 +757,13 @@ namespace BansheeEditor
             else
                 cameraController.EnableInput(false);
 
-            SceneHandles.BeginInput();
-            sceneHandles.UpdateInput(scenePos, Input.PointerDelta);
-            sceneAxesGUI.UpdateInput(scenePos);
-            SceneHandles.EndInput();
+            if (AllowViewportInput)
+            {
+                SceneHandles.BeginInput();
+                sceneHandles.UpdateInput(scenePos, Input.PointerDelta);
+                sceneAxesGUI.UpdateInput(scenePos);
+                SceneHandles.EndInput();
+            }
 
             sceneHandles.Draw();
             sceneAxesGUI.Draw();
@@ -973,6 +1018,34 @@ namespace BansheeEditor
             objects = cleanList.ToArray();
         }
 
+        /// <summary>
+        /// Checks if the load progress bar needs to be shown, shows/hides it and updates the progress accordingly.
+        /// </summary>
+        private void UpdateLoadingProgress()
+        {
+            bool needsProgress = EditorApplication.IsSceneLoading;
+
+            if (needsProgress && !loadingProgressShown)
+            {
+                progressLayout.Active = true;
+                rtPanel.Active = false;
+                sceneAxesPanel.Active = false;
+
+                loadingProgressShown = true;
+            }
+            else if(!needsProgress && loadingProgressShown)
+            {
+                progressLayout.Active = false;
+                rtPanel.Active = true;
+                sceneAxesPanel.Active = true;
+
+                loadingProgressShown = false;
+            }
+
+            if (needsProgress)
+                loadProgressBar.Percent = EditorApplication.SceneLoadProgress;
+        }
+
         /// <summary>
         /// Starts a drag operation that displays a selection outline allowing the user to select multiple entries at once.
         /// </summary>