이번 시간에는 지난 시간에 만든 Widget 버튼을 Unreal C++ 변수와 연결시켜 줄 것이다. 버튼을 누르면 함수가 실행되게 만든다. 그 후, Subsystem 기능들을 가져와 쓸 수 있도록 기본적인 세팅을 할 것이다.

 

 

 


 

 

Button Callbacks 만들기 + SubSystem에 접근하기

 

 


 

 

Button Callback 만들기

 

Menu.h

더보기
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Menu.generated.h"
UCLASS()
class MULTIPLAYERSESSIONS_API UMenu : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void MenuSetup();
protected:
virtual bool Initialize() override;
private:
//meta = (BindWidget)을 사용하면 BP의 Button Widget이 아래의 변수와 연결된다. 이 때 BP와 C++변수 이름은 일치하여야 한다.
UPROPERTY(meta = (BindWidget))
class UButton* HostButton;
UPROPERTY(meta = (BindWidget))
UButton* JoinButton;
UFUNCTION()
void HostButtonClicked();
UFUNCTION()
void JoinButtonClicked();
// The subsystem designed to handle all online session functionality
class UMultiplayerSessionsSubsystem* MultiplayerSessionsSubsystem;
};

Button Callback 만들기

  • 상위 클래스의 Initialize()함수를 override 한다.
    • virtual bool Initialize() override;
  • Button 변수 만들기
    • UPROPERTY(meta = (BindWidget))
      class UButton* HostButton;
    • UPROPERTY(meta = (BindWidget))
      UButton* JoinButton;
    • meta = (BindWidget)을 사용하면 BP의 Button Widget이 아래의 변수와 연결된다. 이 때 BP와 C++변수 이름은 일치하여야 한다.
  • Button을 눌렀을 때 연동되는 함수 만들기
    • UFUNCTION()
      void HostButtonClicked();
    • UFUNCTION()
      void JoinButtonClicked();

 

SubSystem에 접근하기

  • 변수 추가
    • class UMultiplayerSessionsSubsystemMultiplayerSessionsSubsystem;

 

 

 

Menu.cpp

더보기
#include "Menu.h"
#include "Components/Button.h"
#include "MultiplayerSessionsSubsystem.h"
void UMenu::MenuSetup()
{
AddToViewport();
SetVisibility(ESlateVisibility::Visible);
bIsFocusable = true;
UWorld* World = GetWorld();
if (World)
{
APlayerController* PlayerController = World->GetFirstPlayerController();
if (PlayerController)
{
FInputModeUIOnly InputModeData;
InputModeData.SetWidgetToFocus(TakeWidget());
InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
PlayerController->SetInputMode(InputModeData);
PlayerController->SetShowMouseCursor(true);
}
}
UGameInstance* GameInstance = GetGameInstance();
if (GameInstance)
{
//헤더에서 만든 MultiplayerSessionsSubsystem 변수에 Subsystem을 리턴 값을 넣어준다.
MultiplayerSessionsSubsystem = GameInstance->GetSubsystem<UMultiplayerSessionsSubsystem>();
}
}
bool UMenu::Initialize()
{
//Super버젼이 false면 false를 리턴한다.(=상위 클래스에서 Initialize 하는게 없으면 false를 리턴하여 Initialize()를 하지 않는다.)
if (!Super::Initialize())
{
return false;
}
if (HostButton)
{
//HostButton 클릭할 때 발생하는 이벤트를 Delegate로 연결해준다.
HostButton->OnClicked.AddDynamic(this, &ThisClass::HostButtonClicked);
}
if (JoinButton)
{
//JoinButton 클릭할 때 발생하는 이벤트를 Delegate로 연결해준다.
JoinButton->OnClicked.AddDynamic(this, &ThisClass::JoinButtonClicked);
}
return true;
}
void UMenu::HostButtonClicked()
{
//디버깅 테스트
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
15.f,
FColor::Yellow,
FString(TEXT("Host Button Clicked"))
);
}
if (MultiplayerSessionsSubsystem)
{
MultiplayerSessionsSubsystem->CreateSession(4, FString("FreeForAll"));
}
}
void UMenu::JoinButtonClicked()
{
//디버깅 테스트
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
15.f,
FColor::Yellow,
FString(TEXT("Join Button Clicked"))
);
}
}

헤더 추가

  • #include "MultiplayerSessionsSubsystem.h"
    • GetSubsystem<UMultiplayerSessionsSubsystem>()를 사용하기 위해서 위의 헤더를 추가하였.

 

SubSystem에 접근하기

  • void UMenu::MenuSetup()
    • UGameInstance* GameInstance = GetGameInstance();
      if (GameInstance) {
      //헤더에서 만든 MultiplayerSessionsSubsystem 변수에 Subsystem을 리턴 값을 넣어준다.
      MultiplayerSessionsSubsystem GameInstance->GetSubsystem<UMultiplayerSessionsSubsystem>();
      }

 

 

실행화면