/// <summary> /// Unloads the current level and loads the new level /// </summary> private void LoadLevelNow(LevelChangedEventArgs args) { Level newLevel = args.NewLevel; // Unload current level UnloadLevel(args); CurrentLevel = newLevel; // Load new Level if (newLevel != null) { Launch.Log("=========================================================="); Launch.Log("======= Level loading: " + newLevel.Name + " ======="); Launch.Log("=========================================================="); // load our resource group, if we have one InvokeLevelProgress(args, "Initialising new resource group..."); if (ResourceGroupManager.Singleton.ResourceGroupExists(newLevel.Name) && !ResourceGroupManager.Singleton.IsResourceGroupInitialised(newLevel.Name)) { Launch.Log("[Loading] Initialising resource group: " + newLevel.Name); ResourceGroupManager.Singleton.InitialiseResourceGroup(newLevel.Name); } // load up the world definition from the .muffin file InvokeLevelProgress(args, "Reading .muffin files..."); newLevel.ReadMuffin(); // set up shadows, create stuff in the .scene file, and set up physics InvokeLevelProgress(args, "Reading .scene file and setting up shadows and physics..."); LKernel.GetG<SceneManager>().SetupShadows(newLevel); newLevel.ReadDotSceneAndSetupPhysics(); // run our level loading events Launch.Log("[Loading] Loading everything else..."); InvokeLevelProgress(args, "Invoking level load event..."); Invoke(OnLevelLoad, args); // then put Things into our world InvokeLevelProgress(args, "Creating entities..."); newLevel.CreateEntities(); // then load the rest of the handlers InvokeLevelProgress(args, "Loading level handlers..."); LKernel.LoadLevelHandlers(newLevel); IsValidLevel = true; if (IsPlayableLevel) LKernel.GetG<PhysicsMain>().StartSimulation(); // run our scripts InvokeLevelProgress(args, "Running scripts..."); LKernel.GetG<LuaMain>().LoadScriptFiles(newLevel.Name); newLevel.RunLevelScript(); newLevel.RunThingScripts(); InvokeLevelProgress(args, "Building static and instanced geometry..."); LKernel.GetG<StaticGeometryManager>().Build(); LKernel.GetG<InstancedGeometryManager>().Build(); } // if we're on the main menu, pause it if (newLevel.Name == Settings.Default.MainMenuName) Pauser.IsPaused = true; // last bit of cleanup InvokeLevelProgress(args, "Garbage collecting..."); GC.Collect(); // post load event needs to be delayed if (newLevel != null) { // reset these elapsed = 0; frameOneRendered = frameTwoRendered = false; // set up our handler postLoadFrameStartedHandler = new FrameListener.FrameStartedHandler( (fe) => { return DelayedRun_FrameStarted(fe, INITIAL_DELAY, (a) => { Invoke(OnLevelPostLoad, a); }, args); }); LKernel.Get<Root>().FrameStarted += postLoadFrameStartedHandler; } }
/// <summary> /// Loads a level! /// </summary> /// <param name="delay"> /// Minimum time to wait (in seconds) before we load the level, to let stuff like loading screens have a chance to render. /// Pass 0 to load the new level instantly. /// </param> public void LoadLevel(LevelChangeRequest request, float delay = INITIAL_DELAY) { Pauser.IsPaused = false; var eventArgs = new LevelChangedEventArgs(new Level(request.NewLevelName), CurrentLevel, request); // fire our preUnload events Invoke(OnLevelPreUnload, eventArgs); if (delay > 0) { // we need to have this because otherwise we start loading before we manage to render a frame, and we need to render a frame to // show stuff like a loading screen // reset these elapsed = 0; frameOneRendered = frameTwoRendered = false; // set up a little frame started handler with our events preUnloadFrameStartedHandler = new FrameListener.FrameStartedHandler( (fe) => { return DelayedRun_FrameStarted(fe, delay, LoadLevelNow, eventArgs); }); LKernel.Get<Root>().FrameStarted += preUnloadFrameStartedHandler; } else { // if our delay is 0, just load the level and don't do any of the delayed stuff LoadLevelNow(eventArgs); } }