六一的部落格


关关难过关关过,前路漫漫亦灿灿。



Menu Level


说明

主菜单其实是个空关卡, 相对应的, 会需要关卡相关的类

-
STUMenuGameModeBase
STUMenuPlayerController
STUMenuHUD
STUMenuWidget

创建C++类和对应蓝图

创建文件夹

  • Content/Menu
  • Content/Menu/UI
名称 基类 路径 属性
STUMenuGameModeBase GameModeBase Menu Public
STUMenuPlayerController PlayerController Menu Public
STUMenuHUD HUD Menu/UI Public
STUMenuWidget UserWidget Menu/UI Public



C++类 蓝图 路径
STUMenuGameModeBase BP_STUMenuGameModeBase Content/Menu
STUMenuPlayerController BP_STUMenuPlayerController Content/Menu
STUMenuHUD BP_STUMenuHUD Content/Menu/UI
STUMenuWidget WBP_Menu Content/Menu/UI

可以不创建BP_STUMenuPlayerController




创建主菜单

  1. 创建关卡, 命名为 MenuLevel

    Content/Menu

  2. 往关卡中添加指数级高度雾

    Exponential Height Fog

    设置颜色

    -
    Fog Inscattering Color > Hex Linear 0027CFFF


  3. 设置编辑器和游戏默认载入关卡

    Edit > Project Settings.. > Project > Maps & Modes > Default Maps

    -
    Editor Startup Map MenuLevel
    Game Default Map MenuLevel
  4. 设置关卡使用类型

    World Settings

    -
    GameMode Override BP_STUMenuGameModeBase
    HUD Class BP_STUMenuHUD
    Player Controller Class BP_STUMenuPlayerController



设计WBP_Menu

  1. 从WBP_PauseWidget拷贝整个 Canvas Panel

  2. 在WBP_Menu中粘贴 Canvas Panel

  3. 修改文本


  4. 修改按钮文本


  5. 修改按钮变量名



修改头文件搜索路径

ShootThemUp: ShootThemUp.Build.cs

 1PublicIncludePaths.AddRange(new string[]
 2{
 3    "ShootThemUp/Public/Player",
 4    "ShootThemUp/Public/Components",
 5    "ShootThemUp/Public/Dev",
 6    "ShootThemUp/Public/Weapon",
 7    "ShootThemUp/Public/UI",
 8    "ShootThemUp/Public/Animations",
 9    "ShootThemUp/Public/Pickups",
10    "ShootThemUp/Public/Weapon/Components",
11    "ShootThemUp/Public/AI",
12    "ShootThemUp/Public/AI/Tasks",
13    "ShootThemUp/Public/AI/Services",
14    "ShootThemUp/Public/AI/EQS",
15    "ShootThemUp/Public/AI/Decorators",
16    "ShootThemUp/Public/Menu",
17    "ShootThemUp/Public/Menu/UI"
18});

实现STUMenuGameModeBase

添加构造函数, 设置PlayerController和HUD默认类型

public

ShootThemUp: Menu/STUMenuGameModeBase.h

1ASTUMenuGameModeBase();

ShootThemUp: Menu/STUMenuGameModeBase.cpp

1#include "Menu/STUMenuPlayerController.h"
2#include "Menu/UI/STUmenuHUD.h"
3
4ASTUMenuGameModeBase::ASTUMenuGameModeBase()
5{
6    PlayerControllerClass = ASTUMenuPlayerController::StaticClass();
7    HUDClass = ASTUMenuHUD::StaticClass();
8}

实现STUMenuPlayerController

覆写BeginPlay函数, 输入模式为UIOnly, 全程显示鼠标光标

protected

ShootThemUp: Menu/STUMenuPlayerController.h

1virtual void BeginPlay() override;

ShootThemUp: Menu/STUMenuPlayerController.cpp

1void ASTUMenuPlayerController::BeginPlay()
2{
3    Super::BeginPlay();
4
5    bShowMouseCursor = true;
6    SetInputMode(FInputModeUIOnly());
7}

实现STUMenuHUD

覆写BeginPlay函数, 创建窗口部件, 并添加到视口

  1. 添加属性: 保存窗口部件类型

    protected

    ShootThemUp: Menu/UI/STUMenuHUD.h
    1class UUserWidget;
    2
    3UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
    4TSubclassOf<UUserWidget> MenuWidgetClass;
  2. 覆写BeginPlay函数

    protected

    ShootThemUp: Menu/UI/STUMenuHUD.h
    1virtual void BeginPlay() override;
    ShootThemUp: Menu/UI/STUMenuHUD.cpp
     1#include "Blueprint/UserWidget.h"
     2
     3void ASTUMenuHUD::BeginPlay()
     4{
     5    Super::BeginPlay();
     6
     7    if (MenuWidgetClass)
     8    {
     9        const auto MenuWidget = CreateWidget<UUserWidget>(GetWorld(), MenuWidgetClass);
    10        if (MenuWidget)
    11        {
    12            MenuWidget->AddToViewport();
    13        }
    14    }
    15}

实现STUMenuWidget

覆写NativeOnInitialized, 注册按钮点击事件

  1. 添加属性: 按钮

    protected

    ShootThemUp: Menu/UI/STUMenuWidget.h

    1class UButton;
    2
    3UPROPERTY(meta = (BindWidget))
    4UButton *StartGameButton;
  2. 实现回调函数

    不要遗漏UFUNCTION宏

    private

    ShootThemUp: Menu/UI/STUMenuWidget.h

    1UFUNCTION()
    2void OnStartGame();

    ShootThemUp: Menu/UI/STUMenuWidget.cpp

    1#include "Kismet/GameplayStatics.h"
    2
    3void USTUMenuWidget::OnStartGame()
    4{
    5    const FName LevelName = "DefaultMap"; /* StartupLevelName */
    6
    7    UGameplayStatics::OpenLevel(GetWorld(), LevelName);
    8}
  3. 覆写NativeOnInitialized, 注册回调函数

    protected

    ShootThemUp: Menu/UI/STUMenuWidget.h

    1virtual void NativeOnInitialized() override;

    ShootThemUp: Menu/UI/STUMenuWidget.cpp

     1#include "Components/Button.h"
     2
     3void USTUMenuWidget::NativeOnInitialized()
     4{
     5    Super::NativeOnInitialized();
     6
     7    if (StartGameButton)
     8    {
     9        StartGameButton->OnClicked.AddDynamic(this, &USTUMenuWidget::OnStartGame);
    10    }
    11}

查看

在BP_STUMenuHUD中设置窗口部件类型

-
Menu Widget Class WBP_Menu


点击 Start Game 能进入游戏


添加主菜单


Menu Level


说明

主菜单其实是个空关卡, 相对应的, 会需要关卡相关的类

-
STUMenuGameModeBase
STUMenuPlayerController
STUMenuHUD
STUMenuWidget

创建C++类和对应蓝图

创建文件夹

  • Content/Menu
  • Content/Menu/UI
名称 基类 路径 属性
STUMenuGameModeBase GameModeBase Menu Public
STUMenuPlayerController PlayerController Menu Public
STUMenuHUD HUD Menu/UI Public
STUMenuWidget UserWidget Menu/UI Public



C++类 蓝图 路径
STUMenuGameModeBase BP_STUMenuGameModeBase Content/Menu
STUMenuPlayerController BP_STUMenuPlayerController Content/Menu
STUMenuHUD BP_STUMenuHUD Content/Menu/UI
STUMenuWidget WBP_Menu Content/Menu/UI

可以不创建BP_STUMenuPlayerController




创建主菜单

  1. 创建关卡, 命名为 MenuLevel

    Content/Menu

  2. 往关卡中添加指数级高度雾

    Exponential Height Fog

    设置颜色

    -
    Fog Inscattering Color > Hex Linear 0027CFFF


  3. 设置编辑器和游戏默认载入关卡

    Edit > Project Settings.. > Project > Maps & Modes > Default Maps

    -
    Editor Startup Map MenuLevel
    Game Default Map MenuLevel
  4. 设置关卡使用类型

    World Settings

    -
    GameMode Override BP_STUMenuGameModeBase
    HUD Class BP_STUMenuHUD
    Player Controller Class BP_STUMenuPlayerController



设计WBP_Menu

  1. 从WBP_PauseWidget拷贝整个 Canvas Panel

  2. 在WBP_Menu中粘贴 Canvas Panel

  3. 修改文本


  4. 修改按钮文本


  5. 修改按钮变量名



修改头文件搜索路径

ShootThemUp: ShootThemUp.Build.cs

 1PublicIncludePaths.AddRange(new string[]
 2{
 3    "ShootThemUp/Public/Player",
 4    "ShootThemUp/Public/Components",
 5    "ShootThemUp/Public/Dev",
 6    "ShootThemUp/Public/Weapon",
 7    "ShootThemUp/Public/UI",
 8    "ShootThemUp/Public/Animations",
 9    "ShootThemUp/Public/Pickups",
10    "ShootThemUp/Public/Weapon/Components",
11    "ShootThemUp/Public/AI",
12    "ShootThemUp/Public/AI/Tasks",
13    "ShootThemUp/Public/AI/Services",
14    "ShootThemUp/Public/AI/EQS",
15    "ShootThemUp/Public/AI/Decorators",
16    "ShootThemUp/Public/Menu",
17    "ShootThemUp/Public/Menu/UI"
18});

实现STUMenuGameModeBase

添加构造函数, 设置PlayerController和HUD默认类型

public

ShootThemUp: Menu/STUMenuGameModeBase.h

1ASTUMenuGameModeBase();

ShootThemUp: Menu/STUMenuGameModeBase.cpp

1#include "Menu/STUMenuPlayerController.h"
2#include "Menu/UI/STUmenuHUD.h"
3
4ASTUMenuGameModeBase::ASTUMenuGameModeBase()
5{
6    PlayerControllerClass = ASTUMenuPlayerController::StaticClass();
7    HUDClass = ASTUMenuHUD::StaticClass();
8}

实现STUMenuPlayerController

覆写BeginPlay函数, 输入模式为UIOnly, 全程显示鼠标光标

protected

ShootThemUp: Menu/STUMenuPlayerController.h

1virtual void BeginPlay() override;

ShootThemUp: Menu/STUMenuPlayerController.cpp

1void ASTUMenuPlayerController::BeginPlay()
2{
3    Super::BeginPlay();
4
5    bShowMouseCursor = true;
6    SetInputMode(FInputModeUIOnly());
7}

实现STUMenuHUD

覆写BeginPlay函数, 创建窗口部件, 并添加到视口

  1. 添加属性: 保存窗口部件类型

    protected

    ShootThemUp: Menu/UI/STUMenuHUD.h
    1class UUserWidget;
    2
    3UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
    4TSubclassOf<UUserWidget> MenuWidgetClass;
  2. 覆写BeginPlay函数

    protected

    ShootThemUp: Menu/UI/STUMenuHUD.h
    1virtual void BeginPlay() override;
    ShootThemUp: Menu/UI/STUMenuHUD.cpp
     1#include "Blueprint/UserWidget.h"
     2
     3void ASTUMenuHUD::BeginPlay()
     4{
     5    Super::BeginPlay();
     6
     7    if (MenuWidgetClass)
     8    {
     9        const auto MenuWidget = CreateWidget<UUserWidget>(GetWorld(), MenuWidgetClass);
    10        if (MenuWidget)
    11        {
    12            MenuWidget->AddToViewport();
    13        }
    14    }
    15}

实现STUMenuWidget

覆写NativeOnInitialized, 注册按钮点击事件

  1. 添加属性: 按钮

    protected

    ShootThemUp: Menu/UI/STUMenuWidget.h

    1class UButton;
    2
    3UPROPERTY(meta = (BindWidget))
    4UButton *StartGameButton;
  2. 实现回调函数

    不要遗漏UFUNCTION宏

    private

    ShootThemUp: Menu/UI/STUMenuWidget.h

    1UFUNCTION()
    2void OnStartGame();

    ShootThemUp: Menu/UI/STUMenuWidget.cpp

    1#include "Kismet/GameplayStatics.h"
    2
    3void USTUMenuWidget::OnStartGame()
    4{
    5    const FName LevelName = "DefaultMap"; /* StartupLevelName */
    6
    7    UGameplayStatics::OpenLevel(GetWorld(), LevelName);
    8}
  3. 覆写NativeOnInitialized, 注册回调函数

    protected

    ShootThemUp: Menu/UI/STUMenuWidget.h

    1virtual void NativeOnInitialized() override;

    ShootThemUp: Menu/UI/STUMenuWidget.cpp

     1#include "Components/Button.h"
     2
     3void USTUMenuWidget::NativeOnInitialized()
     4{
     5    Super::NativeOnInitialized();
     6
     7    if (StartGameButton)
     8    {
     9        StartGameButton->OnClicked.AddDynamic(this, &USTUMenuWidget::OnStartGame);
    10    }
    11}

查看

在BP_STUMenuHUD中设置窗口部件类型

-
Menu Widget Class WBP_Menu


点击 Start Game 能进入游戏