이번 시간에는 지난 시간에 만든 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>();
        }

     

     

    실행화면