Serfs Up 04 - Main Menu
Building an in game, rendered Main Menu screen in Unreal
Building an animated Main Menu screen in Unreal
In this tutorial we'll walk through building an in game MainMenu screen inside of Unreal Engine. So far in my gaming and game design experience there are two main kind of menu screens I've experienced. The first is a Widget only menu, where the background is a static or animated image and the entire menu is just composed as an interface. The second is where there is a menu "level" created with a set of actors and static meshes that limit player control. I'm excited to play with the latter so this tutorial will focus on an in game rendered level main menu.
Kick things off by going to File, New Level. We'll create an empty level and build everything from scratch. Once the new level has loaded, hit save and call your new level MainMenu. You should now have a completely empty level.
Let there be light
The first thing we need is some light in our level so we're going to use the awesome Env. Light Mixer window to bootstrap some lighting. Go to the Window Menu and open the Env. Light Mixer. We're going to be adding
- Directional Light (This is our pretend sun)
- Skylight (Brightens the entire world by a base amount)
- SkyAtmosphere (Makes it look like we have a sky)
- VolumetricCloud (Clouds in the sky)
- ExponentialHeightFog (Makes the world feel more real)
- SkySphere (Not sure what this is yet TODO)
If you click on each in the Env. Light Mixer you'll soon see a panel of each of the lighting options added to your level. For now we can leave the defaults.
Land Ho
The second thing our level needs is some land. Open LandScape mode by grabbing the "Selection Mode" dropdown and choose Landscape or press Shift + 2. Once you're in Landscape mode, we're going to create a 3x3 landscape with the default settings and hit create.
For our Main Menu level, I want to have some mountains and forests in the background so let's start by using the sculpt tool to add some random height to the level. Go wild, there's no wrong answers here and when you're done you should have something in the general vicinity of
Stage a scene
If you don't have an asset pack already now would be a good time to track one down, for this tutorial we're using Advanced Village Pack but really anything works. Drag and drop your environment and props and set your landscape material until you've staged a reasonable backdrop to your main menu.
Mine looks like this but you don't need to add as much detail for your own version just yet. You can curate, craft and sweat the small details later as much as you like.
Creating the MainMenuHUD Widget
Now that we've got our scene staged we can start to work on the interface itself. Create a new Widget actors
SerfsUp/Core/UserInteface/WBP_MainMenuHUD
For now let's keep it super simple and just create a Canvas panel with a vertical box, the game title and 3 buttons.
Lastly, this is not production ready at all since opening a level this way runs in the main thread and will effectively just pause your game until the loading is done but lets hook up an open level event to the new game button on click event.
Creating the MainMenuHUD HUD class
We need to setup a HUD that's specific to our main menu. The difference between this and the GameHUD is that the MainMenuHUD will not implement our GameHUDInterface and will not allow the player to interact with the Character.
Public/Game/MainMenuHUD.h
// This work is licensed under a Creative Commons Attribution 4.0 International License https://creativecommons.org/licenses/by/4.0/
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "Blueprint/UserWidget.h"
#include "MainMenuHUD.generated.h"
/**
*
*/
UCLASS()
class SERFSUP_API AMainMenuHUD : public AHUD
{
GENERATED_BODY()
public:
AMainMenuHUD();
protected:
// To add mapping context
virtual void BeginPlay();
private:
/* Widget */
TSubclassOf<class UUserWidget> HUDWidgetClass;
UUserWidget *HUDWidget;
};
Private/Game/MainMenuHUD.cpp
// This work is licensed under a Creative Commons Attribution 4.0 International License https://creativecommons.org/licenses/by/4.0/
#include "Game/MainMenuHUD.h"
AMainMenuHUD::AMainMenuHUD()
{
ConstructorHelpers::FClassFinder<UUserWidget> WidgetClassFinder(TEXT("WidgetBlueprint'/Game/SerfsUp/Core/UserInterface/WBP_MainMenuHUD'"));
if (WidgetClassFinder.Succeeded())
{
HUDWidgetClass = WidgetClassFinder.Class;
}
}
void AMainMenuHUD::BeginPlay()
{
// Call the base class
Super::BeginPlay();
// Create our HUDWidget
HUDWidget = CreateWidget<UUserWidget>(PlayerOwner, HUDWidgetClass);
// Add it to the viewport to be rendered
HUDWidget->AddToViewport(0);
// Set the input mode to UI only
PlayerOwner->SetInputMode(FInputModeUIOnly());
// Show the mouse cursor for the player
PlayerOwner->SetShowMouseCursor(true);
}
Creating the MainMenuGameMode
Similar to the HUD class above, we want to have a separate GameMode that sets a lot of the game options to more useful defaults for a non-interactable level.
Public/Game/SerfsUpMainMenuMode.h
// This work is licensed under a Creative Commons Attribution 4.0 International License https://creativecommons.org/licenses/by/4.0/
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "SerfsUpMainMenuMode.generated.h"
UCLASS(minimalapi)
class ASerfsUpMainMenuMode : public AGameModeBase
{
GENERATED_BODY()
public:
ASerfsUpMainMenuMode();
};
Private/Game/SerfsUpMainMenuMode.cpp
// This work is licensed under a Creative Commons Attribution 4.0 International License https://creativecommons.org/licenses/by/4.0/
#include "Game/SerfsUpMainMenuMode.h"
#include "Game/MainMenuHUD.h"
#include "UObject/ConstructorHelpers.h"
ASerfsUpMainMenuMode::ASerfsUpMainMenuMode()
{
// Setup the HUD
HUDClass = AMainMenuHUD::StaticClass();
// We don't set our PlayerController or PlayerCharacter or Pawn as the default ones are just fine for this scene
// Set the game mode to start all players as spectators so we load pawns instead of the PlayerCharacter
bStartPlayersAsSpectators = true;
}
Camera, Action
Now that all of the core classes exist, it's time to put it all together, add a camera and setup our level to be our new default level for the program.
Open the MainMenu level and go to WorldDetails and change the GameMode Override to SerfsUpMainMenuMode per below. You'll see all the default GameMode objects setup.
The last step now is to add a default Camera to the level that will be our viewpoint into the MainMenu scene. Add a new CameraActor and position it wherever looks best, I named the camera MenuCamera and set it to slightly above the scene.
To set the MenuCamera to be the default camera we need to open the Level Blueprint
We want to call Set View Target with Blend on Event BeginPlay and set the New View Target to be MenuCamera
Fin
Et Voila