5. 2차 메뉴 제작

새로운 기능의 2차 메뉴를 만듭니다.

Windows
MacOS
Linux
On this page
  1. 콘텐츠 브라우저 에서 아까 만든 "NewGameMenu" 애셋을 찾아 엽니다. 이 메뉴에는 이름 입력 텍스트 박스 와, 이름을 입력하기 전까지는 누를 수 없는 '게임 플레이' 버튼, 메인 메뉴로 돌아가는 버튼 이 들어있습니다.

  2. 이름 입력 박스를 만들기 위해, 레이아웃에 (텍스트 블록 이 아닌) Text Box (텍스트 박스) 를 끌어 놓습니다.

    CreateTextEntryBox.png

  3. 텍스트 박스 환경설정은 다음과 같이 합니다: 이름을 NameTextEntry 로 바꿉니다. 위치는 (325, 200) 입니다. 텍스트 박스 왼쪽에 위치한 텍스트 블록 을 남겨둡니다. 크기는 250x40 입니다. ("Style" 제목 아래) 폰트 크기는 20 입니다.

    TextBoxDetails.png

  4. 이전 메뉴에서 버튼 을 만들었던 것과 같은 방식으로 텍스트 블록 라벨이 있는 게임 플레이 버튼 을 만들면 됩니다. 버튼의 경우: 이름은 PlayGameButton, Position 은 200, 300, Size 는 200, 100 으로 변경합니다. 텍스트 블록의 경우: 이름을 PlayGameText 로, Visibility 를 Hit Test Visible 로 변경한 다음 PlayGameButton 위에 끌어놓습니다.

  5. 게임 플레이 버튼 에는 특별한 기능이 있습니다. 텍스트 박스 에 입력된 이름이 공백이 아닐 때만 활성화되는 것입니다. UMG 의 "바인드" 기능을 사용하여 (Behavior 섹션 아래) "Is Enabled" 칸에 새로운 함수를 만들면 됩니다.

    PlayGameButtonDetails.png

    게임에서 쓸 수 있는 플레이어 이름을 결정하는 데 복잡한 규칙이 있다거나, 이름을 C++ 변수로 저장할 필요가 있는 경우, 게임 모드UFUNCTION 또는 프로젝트 내 어딘가에 스태틱 함수로 노출시켜야 할 것입니다. 하지만 이름 문자열이 공백만 아니면 되니, 위젯 에서 바로 스크립트를 짜 주면 되겠습니다.

  6. 오직 텍스트 박스 가 공백이 아닐 경우에만 버튼 이 활성화되었는지 확인하려면, 텍스트 박스 에서의 텍스트를 스트링으로 변환한 다음 길이가 0 보다 큰지 검사하면 됩니다. 로직은 이렇습니다:

    PlayGameButtonEnableFunction.png

  7. 여기서 메인 메뉴로 돌아나갈 수 있도록 버튼 을 하나 더 추가해 봅시다. 메인 메뉴에서 게임 플레이 버튼 과 비슷하지만, 위치 기준이 좌상단이 아닌 우하단 구석이 될 것입니다. 그러기 위해서는, 버튼디테일 패널 에서 "앵커" 드롭다운을 클릭한 다음, 팝업 메뉴에서 우하단 부분을 나타내는 모양을 선택합니다. 이름을 MainMenuButton 으로 바꿉니다. Position 을 -400, -200 으로 설정합니다. * **Size** 를 200x100 으로 설정합니다.

    SelectAnchor.png

    앵커를 우하단 구석으로 지정한다고 크기나 위치값 작동 방식이 변하는 것은 아니므로, 위치 값을 음수로 해 줘야 화면에 보이게 됩니다. 크기 값은 양수로 둡니다.

  8. 이제 OnClicked 이벤트를 한 번 더 추가하는 것으로 새 버튼 에 스크립트를 추가하겠습니다. 메인 메뉴 버튼 은 단순히 메인 메뉴 위젯 을 로드하는 반면, 게임 플레이 버튼ChangeMenuWidget 함수로의 호출에 새로운 위젯 을 전혀 제공하지 않는 것으로 메뉴를 비활성화시킵니다. 이는 실제 클래스 또는 애셋 이름 대신 "Select Class" (클래스 선택)이라 되어있는 문구로 알 수 있습니다.

    NewGameButtonBPs.png

    게임 플레이 버튼 으로 메뉴를 비활성화시킨 이후, 게임에서 더이상 아무것도 할 수 없게 됩니다. 보통 이 시점에서 첫 레벨을 로드하고, 오프닝 동영상을 재생한 뒤 을 스폰시켜 빙의하거나 하게 됩니다.

  9. 거의 아래와 같은 스크린샷이 두 개 생겼을 것입니다.

    FinalScreen.png

    FinalScreen2.png

완성 코드

HowTo_UMG.Build.cs

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class HowTo_UMG : ModuleRules
{
    public HowTo_UMG(TargetInfo Target)
    {
        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });

        //PrivateDependencyModuleNames.AddRange(new string[] {  });

        // Uncomment if you are using Slate UI
        PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");
        // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
        // {
        //      if (UEBuildConfiguration.bCompileSteamOSS == true)
        //      {
        //          DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
        //      }
        // }
    }
}

HowTo_UMGGameMode.h

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Blueprint/UserWidget.h"
#include "GameFramework/GameModeBase.h"
#include "HowTo_UMGGameMode.generated.h"

/**
    * 
    */
UCLASS()
class HOWTO_UMG_API AHowTo_UMGGameMode : public AGameModeBase
{
    GENERATED_BODY()

public:
    /** Remove the current menu widget and create a new one from the specified class, if provided. */
    UFUNCTION(BlueprintCallable, Category = "UMG Game")
    void ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass);

protected:
    /** Called when the game starts. */
    virtual void BeginPlay() override;

    /** The widget class we will use as our menu when the game starts. */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UMG Game")
    TSubclassOf<UUserWidget> StartingWidgetClass;

    /** The widget instance that we are using as our menu. */
    UPROPERTY()
    UUserWidget* CurrentWidget;
};

HowTo_UMGGameMode.cpp

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

#include "HowTo_UMG.h"
#include "HowTo_UMGGameMode.h"

void AHowTo_UMGGameMode::BeginPlay()
{
    Super::BeginPlay();
    ChangeMenuWidget(StartingWidgetClass);
}

void AHowTo_UMGGameMode::ChangeMenuWidget(TSubclassOf<UUserWidget> NewWidgetClass)
{
    if (CurrentWidget != nullptr)
    {
        CurrentWidget->RemoveFromViewport();
        CurrentWidget = nullptr;
    }
    if (NewWidgetClass != nullptr)
    {
        CurrentWidget = CreateWidget<UUserWidget>(GetWorld(), NewWidgetClass);
        if (CurrentWidget != nullptr)
        {
            CurrentWidget->AddToViewport();
        }
    }
}

HowTo_UMGPlayerController.h

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/PlayerController.h"
#include "HowTo_UMGPlayerController.generated.h"

/**
    * 
    */
UCLASS()
class HOWTO_UMG_API AHowTo_UMGPlayerController : public APlayerController
{
    GENERATED_BODY()

public:
    virtual void BeginPlay() override;
};

HowTo_UMGPlayerController.cpp

// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.

#include "HowTo_UMG.h"
#include "HowTo_UMGPlayerController.h"

void AHowTo_UMGPlayerController::BeginPlay()
{
    Super::BeginPlay();
    SetInputMode(FInputModeGameAndUI());
}
Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback