You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unreal Engine C++开发Pong游戏:不使用Level Blueprint如何显示UMG主菜单?

Alternative Ways to Display Your Main Menu in Unreal Engine Without Level Blueprints

Hey there! Great question—moving away from Level Blueprints for your main menu logic is a fantastic call for keeping your Pong project clean and easy to maintain as you expand it. Let’s break down the most common, industry-standard approaches to handle this in C++:

1. Custom Game Mode Class

Game Modes are the go-to for handling game session initialization, so this is perfect for showing your main menu when the game starts. Here’s how to set it up:

  • Create a new C++ class inheriting from AGameModeBase (name something like APongGameMode)
  • In its BeginPlay() method, add code to load and spawn your main menu widget
  • Set this Game Mode as your project’s default in Project Settings > Maps & Modes

Example Code

Header (.h)

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "PongGameMode.generated.h"

UCLASS()
class PONG_API APongGameMode : public AGameModeBase
{
    GENERATED_BODY()

protected:
    // Runs when the game session starts
    virtual void BeginPlay() override;

private:
    // Assign your main menu widget blueprint here in the editor
    UPROPERTY(EditAnywhere, Category = "UI")
    TSubclassOf<class UUserWidget> MainMenuWidgetClass;

    // Keep a reference to the spawned menu widget
    UUserWidget* CurrentMainMenu;
};

Source (.cpp)

#include "PongGameMode.h"
#include "UI/MainMenuWidget.h" // Replace with your widget's header
#include "Kismet/GameplayStatics.h"

void APongGameMode::BeginPlay()
{
    Super::BeginPlay();

    // Only proceed if we've assigned a widget class in the editor
    if (MainMenuWidgetClass)
    {
        CurrentMainMenu = CreateWidget<UUserWidget>(GetWorld(), MainMenuWidgetClass);
        if (CurrentMainMenu)
        {
            // Add the menu to the screen
            CurrentMainMenu->AddToViewport();

            // Configure input to work with the menu (mouse cursor, UI focus)
            APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);
            if (PlayerController)
            {
                FInputModeUIOnly InputMode;
                InputMode.SetWidgetToFocus(CurrentMainMenu->TakeWidget());
                InputMode.SetLockMouseToViewportBehavior(EMouseLockMode::LockInFullscreen);
                PlayerController->SetInputMode(InputMode);
                PlayerController->SetShowMouseCursor(true);
            }
        }
    }
}

2. Custom Game Instance Class

Game Instances exist for the entire lifespan of your game (not just a single level), so this is ideal if you want to show the menu before any level loads, or keep it persistent across level switches.

  • Create a C++ class inheriting from UGameInstance (name like UPongGameInstance)
  • Override the Init() method to spawn your menu
  • Set this as your default Game Instance in Project Settings > Project > Game Instance Class

Example Code

Header (.h)

#pragma once

#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "PongGameInstance.generated.h"

UCLASS()
class PONG_API UPongGameInstance : public UGameInstance
{
    GENERATED_BODY()

public:
    // Runs when the game first starts up
    virtual void Init() override;

private:
    UPROPERTY(EditAnywhere, Category = "UI")
    TSubclassOf<class UUserWidget> MainMenuWidgetClass;

    UUserWidget* MainMenuWidget;
};

Source (.cpp)

#include "PongGameInstance.h"
#include "UI/MainMenuWidget.h"
#include "Kismet/GameplayStatics.h"

void UPongGameInstance::Init()
{
    Super::Init();

    if (MainMenuWidgetClass)
    {
        MainMenuWidget = CreateWidget<UUserWidget>(this, MainMenuWidgetClass);
        if (MainMenuWidget)
        {
            MainMenuWidget->AddToViewport();

            // Set up input for the menu
            APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);
            if (PlayerController)
            {
                FInputModeUIOnly InputMode;
                InputMode.SetWidgetToFocus(MainMenuWidget->TakeWidget());
                PlayerController->SetInputMode(InputMode);
                PlayerController->SetShowMouseCursor(true);
            }
        }
    }
}

3. Custom Player Controller Class

Player Controllers handle player input and view management, so this works well if your menu is tied to player-specific actions (like pressing a key to open a pause menu). For your main menu, it’s still a valid option—especially if you want to handle menu input logic directly in the Player Controller.

  • Create a C++ class inheriting from APlayerController (name like APongPlayerController)
  • Spawn the menu in BeginPlay() or a custom input handler

Example Code

Header (.h)

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "PongPlayerController.generated.h"

UCLASS()
class PONG_API APongPlayerController : public APlayerController
{
    GENERATED_BODY()

protected:
    virtual void BeginPlay() override;

private:
    UPROPERTY(EditAnywhere, Category = "UI")
    TSubclassOf<class UUserWidget> MainMenuWidgetClass;

    UUserWidget* MainMenuWidget;
};

Source (.cpp)

#include "PongPlayerController.h"
#include "UI/MainMenuWidget.h"

void APongPlayerController::BeginPlay()
{
    Super::BeginPlay();

    if (MainMenuWidgetClass)
    {
        MainMenuWidget = CreateWidget<UUserWidget>(this, MainMenuWidgetClass);
        if (MainMenuWidget)
        {
            MainMenuWidget->AddToViewport();
            SetInputMode(FInputModeUIOnly());
            SetShowMouseCursor(true);
        }
    }
}

Quick Tips to Keep in Mind

  • Use TSubclassOf<UUserWidget> to reference your widget blueprint—this lets you assign it directly in the Unreal Editor without hardcoding file paths.
  • Always configure the input mode when showing the menu: FInputModeUIOnly ensures the mouse interacts with the menu instead of the game world, and SetShowMouseCursor(true) makes the cursor visible.
  • For your Pong game, starting with a Custom Game Mode is likely the simplest choice—it ties the menu initialization directly to the start of your game session, which is exactly what you need for a main menu.

内容的提问来源于stack exchange,提问作者VansFannel

火山引擎 最新活动