Replicated

[Drag Down] 매치메이킹 UI 본문

언리얼 엔진/Drag Down

[Drag Down] 매치메이킹 UI

라구넹 2025. 5. 12. 14:35

방 생성은 룸 이름을 넣어서 가능

 

Find Room 하면 현재 존재하는 룸의 리스트를 보여줌

Join 시 방에 입장 가능

 

블루프린트 구조

 

Create Room의 경우 Editable Text에서 텍스트를 읽어와서 룸 생성 리퀘스트

 

룸 엔트리는 이렇게 생겼는데

 

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Subsystem/DDHttpApiSubsystem.h"
#include "DDRoomEntryWidget.generated.h"

/**
 * 
 */
UCLASS()
class DRAGDOWN_API UDDRoomEntryWidget : public UUserWidget
{
	GENERATED_BODY()
	
public:
	virtual void NativeConstruct() override;

	UFUNCTION(BlueprintCallable)
	void SetRoomEntryWidget(FRoomSummary RoomSummary);

	UFUNCTION()
	void JoinRoom();

protected:
	UPROPERTY(meta = (BindWidget))
	TObjectPtr<class UTextBlock> TxtRoomName;

	UPROPERTY(meta = (BindWidget))
	TObjectPtr<class UTextBlock> TxtHostUserName;

	UPROPERTY(meta = (BindWidget))
	TObjectPtr<class UTextBlock> TxtPlayerCount;

	UPROPERTY(meta = (BindWidget))
	TObjectPtr<class UButton> BtnJoinRoom;

	FString RoomID;
};

// Fill out your copyright notice in the Description page of Project Settings.


#include "UI/DDRoomEntryWidget.h"
#include "Components/Button.h"
#include "Components/TextBlock.h"
#include "DragDown.h"

void UDDRoomEntryWidget::NativeConstruct()
{
	if (BtnJoinRoom)
	{
		BtnJoinRoom->OnClicked.AddDynamic(this, &UDDRoomEntryWidget::JoinRoom);
	}
}

void UDDRoomEntryWidget::SetRoomEntryWidget(FRoomSummary RoomSummary)
{
	RoomID = RoomSummary.RoomId;

	if (TxtRoomName)
	{
		TxtRoomName->SetText(FText::FromString(RoomSummary.RoomName ));
	}

	if (TxtHostUserName)
	{
		TxtHostUserName->SetText(FText::FromString(RoomSummary.HostUserName));
	}

	if ( TxtPlayerCount )
	{
		FString Count = FString::Printf(TEXT("%d / %d"), RoomSummary.CurrentPlayerCount, RoomSummary.MaxPlayers);
		TxtPlayerCount->SetText(FText::FromString(Count));
	}

	UE_LOG(LogDD, Log, TEXT("Room: %s, Host: %s, Players %d - %d"),
		*RoomSummary.RoomName,
		*RoomSummary.HostUserName,
		RoomSummary.CurrentPlayerCount,
		RoomSummary.MaxPlayers);
}

void UDDRoomEntryWidget::JoinRoom()
{
	UDDHttpApiSubsystem* HttpSubsystem = GetGameInstance()->GetSubsystem<UDDHttpApiSubsystem>();
	if (HttpSubsystem == nullptr)
	{
		UE_LOG(LogDD, Error, TEXT("No UDDHttpApiSubsystem"));
	}

	FString IP = HttpSubsystem->GetIP();
	int32 Port = FCString::Atoi( *HttpSubsystem->GetPort() );

	HttpSubsystem->SendJoinRoomRequest(RoomID, IP, Port);
}

FRoomSummary 읽어서 위젯 세팅할 수 있도록 코드 작성

 

런타임에 엔트리가 추가될 수 있도록 구성

 

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Subsystem/DDHttpApiSubsystem.h"
#include "DDRoomListWidget.generated.h"

/**
 * 
 */
UCLASS()
class DRAGDOWN_API UDDRoomListWidget : public UUserWidget
{
	GENERATED_BODY()
	
public:
	UFUNCTION(BlueprintCallable)
	void SetRoomList(TArray< FRoomSummary > RoomSummries);

protected:
	UPROPERTY(meta = (BindWidget))
	TObjectPtr<class UVerticalBox> VerticalBox;

	UPROPERTY(EditAnywhere, BlueprintReadOnly)
	TSubclassOf<class UDDRoomEntryWidget> EntryWidgetToList;
};

// Fill out your copyright notice in the Description page of Project Settings.


#include "UI/DDRoomListWidget.h"
#include "UI/DDRoomEntryWidget.h"
#include "Components/VerticalBox.h"
#include "DragDown.h"

void UDDRoomListWidget::SetRoomList(TArray<FRoomSummary> RoomSummries)
{
	VerticalBox->ClearChildren();

	if ( EntryWidgetToList == nullptr )
	{
		UE_LOG(LogDD, Log, TEXT("UDDRoomListWidget::SetRoomList - No Widget To List"));
	}

	if ( VerticalBox == nullptr )
	{
		UE_LOG(LogDD, Log, TEXT("UDDRoomListWidget::SetRoomList - No Vertical Box"));
	}

	for ( FRoomSummary& RoomSummary : RoomSummries )
	{
		UDDRoomEntryWidget* EntryWidget = NewObject<UDDRoomEntryWidget>(this, EntryWidgetToList);
		if (EntryWidget == nullptr)
		{
			UE_LOG(LogDD, Log, TEXT("UDDRoomListWidget::SetRoomList - WidgetToList Creation Failed"));
			return;
		}
		
		VerticalBox->AddChild(EntryWidget);
		EntryWidget->SetRoomEntryWidget(RoomSummary);
		EntryWidget->Padding = 5.0f;
		
	}
}

버티컬 박스 안에 런타임에 위젯이 추가될 수 있도록 구성

 

주의할 점은, AddChild를 해야 에셋 바인딩이 되어서 (Construct 시점 문제)

그 이후에 위젯 내용 설정을 해주는 함수를 써야 함