From 6234d367b94eb67812a71fef7260d6db3f174c13 Mon Sep 17 00:00:00 2001 From: chrisgregan Date: Tue, 24 Jun 2014 17:21:18 +0100 Subject: [PATCH] Added scene loader component to display loading image --- Assets/Fungus/Prefabs/Game.prefab | Bin 38184 -> 38280 bytes Assets/Fungus/Scripts/Game.cs | 19 ++-- Assets/Fungus/Scripts/SceneLoader.cs | 118 ++++++++++++++++++++++ Assets/Fungus/Scripts/SceneLoader.cs.meta | 8 ++ 4 files changed, 134 insertions(+), 11 deletions(-) create mode 100644 Assets/Fungus/Scripts/SceneLoader.cs create mode 100644 Assets/Fungus/Scripts/SceneLoader.cs.meta diff --git a/Assets/Fungus/Prefabs/Game.prefab b/Assets/Fungus/Prefabs/Game.prefab index 8cd9c30862a4ac48a24526ea17f7e8b012e5f6d8..7ecb1c0b3668d6ae174f4787725e1b50d5354cf3 100644 GIT binary patch delta 261 zcmZ3nim78YlK=xlR}cfk)D8v)22LQmV4{FMqsZos?3bB0E3>R+oIFRBTPP<#F(orE z-7_~aJ(Yn2s8VV2Mpc!`B5V$mFS5!ps!smEsxo;#oBiZqHucGj>~WKCuxT=CgG3p1 zCU4YJVbleZ!jt3Kg&6fV7qPPmG0FgKILo}*O*Y?e^POxV>A)523=IE)pa^KX)91Ae z2|&lR0NMYbVlF_j7eFx+px9rim>W<`fs2751Ss|gD&_$cs{o2sY_@NI$TWFEKl^5d gt^m$S-3pTxrm$?DGueZY9cT=vY>=}hO8**G`-mJ{BmT__bn>?e^Zva{-Ed z0E(Fa#r{IY+<;;lTnr2$K(RkiF%O_v15m7B^NjX~Oq(0J0yrl>=w_MxWQxY-FOxkO JC%a5_0RWp;Ox^$h diff --git a/Assets/Fungus/Scripts/Game.cs b/Assets/Fungus/Scripts/Game.cs index a78d81a3..d6ab3160 100644 --- a/Assets/Fungus/Scripts/Game.cs +++ b/Assets/Fungus/Scripts/Game.cs @@ -51,6 +51,11 @@ namespace Fungus */ public Dialog dialog; + /** + * Loading image displayed when loading a scene using MoveToScene() + */ + public Texture2D loadingImage; + /** * Global dictionary of integer values for storing game state. */ @@ -213,23 +218,15 @@ namespace Fungus } /** - * Loads a new scene. + * Loads a new scene and displays an optional loading image. * This is useful for splitting a large Fungus game across multiple scene files to reduce peak memory usage. - * All previously loaded assets (including textures) will be released. + * All previously loaded assets (including textures and audio) will be released. * @param sceneName The filename of the scene to load. * @param saveGame Automatically save the current game state as a checkpoint. */ public void LoadScene(string sceneName, bool saveGame) { - Application.LoadLevel(sceneName); - - if (saveGame) - { - SaveGame("Fungus.Save"); - } - - // Free up memory used by textures in previous scene - Resources.UnloadUnusedAssets(); + SceneLoader.LoadScene(sceneName, loadingImage, saveGame); } /** diff --git a/Assets/Fungus/Scripts/SceneLoader.cs b/Assets/Fungus/Scripts/SceneLoader.cs new file mode 100644 index 00000000..aa0da59e --- /dev/null +++ b/Assets/Fungus/Scripts/SceneLoader.cs @@ -0,0 +1,118 @@ +using UnityEngine; +using System.Collections; +using System; + +namespace Fungus +{ + /** + * Helper component for loading a new scene. + * A fullscreen loading image is displayed while loading the new scene. + * All Rooms are destroyed and unused assets are released from memory before loading the new scene to minimize memory footprint. + * For streaming Web Player builds, the loading image will be displayed until the requested level has finished downloading. + */ + public class SceneLoader : MonoBehaviour + { + Texture2D loadingTexture; + string sceneToLoad; + bool displayedImage; + bool saveCheckpoint; + + /** + * Asynchronously load a new scene. + * @param _sceneToLoad The name of the scene to load. Scenes must be added in project build settings. + * @param _loadingTexture Loading image to display while loading the new scene. + * @param _saveCheckpoint Automatically save a checkpoint once the new scene has loaded. + */ + static public void LoadScene(string _sceneToLoad, Texture2D _loadingTexture, bool _saveCheckpoint) + { + // Unity does not provide a way to check if the named scene actually exists in the project. + GameObject go = new GameObject(); + DontDestroyOnLoad(go); + + SceneLoader sceneLoader = go.AddComponent(); + sceneLoader.sceneToLoad = _sceneToLoad; + sceneLoader.loadingTexture = _loadingTexture; + sceneLoader.saveCheckpoint = _saveCheckpoint; + } + + void Start() + { + StartCoroutine(DoLoadSequence()); + } + + IEnumerator DoLoadSequence() + { + // Wait until loading image has been displayed in OnGUI + while (loadingTexture != null && + !displayedImage) + { + yield return new WaitForEndOfFrame(); + } + + // Destroy all Room objects to release references to most game assets + Room[] rooms = GameObject.FindObjectsOfType(); + foreach (Room room in rooms) + { + Destroy(room.gameObject); + } + + yield return new WaitForEndOfFrame(); + + // Most big assets should no longer be referenced, so unload them. + Resources.UnloadUnusedAssets(); + + // Wait until scene has finished downloading (WebPlayer only) + while (!Application.CanStreamedLevelBeLoaded(sceneToLoad)) + { + yield return new WaitForEndOfFrame(); + } + + // Load the scene (happens at end of frame) + Application.LoadLevel(sceneToLoad); + + yield return new WaitForEndOfFrame(); + + // Clean up any remaining unused assets + Resources.UnloadUnusedAssets(); + + // Save a checkpoint if required + if (saveCheckpoint) + { + Game game = Game.GetInstance(); + if (game != null) + { + game.SaveGame("Fungus.Save"); + } + } + + // We're now finished with the SceneLoader + Destroy(gameObject); + } + + void OnGUI() + { + if (loadingTexture == null) + { + return; + } + + GUI.depth = -2000; + + float h = Screen.height; + float w = (float)loadingTexture.width * (h / (float)loadingTexture.height); + + float x = Screen.width / 2 - w / 2; + float y = 0; + + Rect rect = new Rect(x, y, w, h); + + GUI.DrawTexture(rect, loadingTexture); + + if (Event.current.type == EventType.Repaint) + { + // Flag that image is now being shown + displayedImage = true; + } + } + } +} diff --git a/Assets/Fungus/Scripts/SceneLoader.cs.meta b/Assets/Fungus/Scripts/SceneLoader.cs.meta new file mode 100644 index 00000000..51696980 --- /dev/null +++ b/Assets/Fungus/Scripts/SceneLoader.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9ee7614beacb8470ea7b51740476f43c +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: