Unreal Engine - 데디케이티드 서버 9 (게임 종료)

2025. 5. 4. 04:22·Unreal Engine

1. 캐릭터 Death 처리


 

흐름

  • StatComponent의 OnOutOfCurrentHP -> PlayerCharacter와 Delegate 바인딩
  • PlayerCharacter -> PlayerController
  • PlayerController -> GameMode

 

코드

//게임 모드
void ADXGameModeBase::OnCharacterDead(ADXPlayerController* InController)
{
	if (!IsValid(InController) || AlivePlayerControllers.Find(InController) == INDEX_NONE)
	{
		return;
	}
	AlivePlayerControllers.Remove(InController);
	DeadPlayerControllers.Add(InController);
} 

//플레이어 컨트롤러
void ADXPlayerController::OnCharaterDead()
{
	ADXGameModeBase* GameMode = Cast<ADXGameModeBase>(UGameplayStatics::GetGameMode(this));
	//server
	if (HasAuthority() && IsValid(GameMode))
	{
		GameMode->OnCharacterDead(this);
	}
}

//플레이어 캐릭터
void ADXPlayerCharacter::BeginPlay()
{
	...
	StatusComponent->OnOutOfCurrentHP.AddUObject(this, &ThisClass::OnDeath);
}

void ADXPlayerCharacter::OnDeath()
{
	ADXPlayerController* PlayerController = GetController<ADXPlayerController>();
	//server
	if (IsValid(PlayerController) && HasAuthority())
	{
		PlayerController->OnCharaterDead();
	}
}

 

 

2. 게임 종료 UI 출력


PlayerController에서 Client RPC 함수를 통해 구현

  • 각 캐릭터마다 각각의 UI를 출력하기 때문에 Client RPC로 구현하기

 

코드

void ADXPlayerController::ClientRPCShowGameResultWidget_Implementation(int32 InRanking)
{
	if (IsLocalController())
	{
		if (IsValid(GameResultUIClass))
		{
			UUW_GameResult* GameResultUI = CreateWidget<UUW_GameResult>(this, GameResultUIClass);
			if (IsValid(GameResultUI))
			{
				GameResultUI->AddToViewport(3);

				FString GameResultString = FString::Printf(TEXT("%s"), InRanking == 1 ? TEXT("Winner Winner Chicken Dinner!") : TEXT("Better Luck Next Time!"));
				GameResultUI->ResultText->SetText(FText::FromString(GameResultString));

				FString RankingString = FString::Printf(TEXT("#%02d"), InRanking);
				GameResultUI->RankingText->SetText(FText::FromString(RankingString));

				FInputModeUIOnly Mode;
				Mode.SetWidgetToFocus(GameResultUI->GetCachedWidget());
				SetInputMode(Mode);

				bShowMouseCursor = true;
			}
		
		}
	}
}

 

GameMode에 UI를 출력해주는 로직 추가

void ADXGameModeBase::OnMainTimerElapsed()
{
	ADXGameStateBase* DXGameState = GetGameState<ADXGameStateBase>();

	if (!IsValid(DXGameState))
	{
		return;
	}

	switch (DXGameState->MatchState)
	{
	...
	case EMatchState::Playing:
	{
		...
		if (DXGameState->AlivePlayerControllerCount <= 1)
		{
			DXGameState->MatchState = EMatchState::Enging;
                        //UI출력
	                AlivePlayerControllers[0]->ClientRPCShowGameResultWidget(1);
		}
		break;
	}
	...
	}
}

void ADXGameModeBase::OnCharacterDead(ADXPlayerController* InController)
{
	if (!IsValid(InController) || AlivePlayerControllers.Find(InController) == INDEX_NONE)
	{
		return;
	}
        //UI 출력
	InController->ClientRPCShowGameResultWidget(AlivePlayerControllers.Num());
	AlivePlayerControllers.Remove(InController);
	DeadPlayerControllers.Add(InController);
}

 

 

3. Title 레벨로 나가기


흐름

  • GameResult UI에 버튼 추가
  • OpenLevel 함수를 통해 Title 레벨로 이동
더보기
#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "UW_GameResult.generated.h"

class UTextBlock;
class UButton;

UCLASS()
class SCC_DEDICATEDX_API UUW_GameResult : public UUserWidget
{
	GENERATED_BODY()

protected:
	virtual void NativeConstruct() override;

private:
	UFUNCTION()
	void OnReturnToTitleButtonClicked();
		
public:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (BindWidget))
	TObjectPtr<UTextBlock> ResultText;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (BindWidget))
	TObjectPtr<UTextBlock> RankingText;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (BindWidget))
	TObjectPtr<UButton> ReturnToTitleButton;
};

 

#include "UI/UW_GameResult.h"

#include "Components/Button.h"
#include "Kismet/GameplayStatics.h"

void UUW_GameResult::NativeConstruct()	
{
	Super::NativeConstruct();

	if (!ReturnToTitleButton.Get()->OnClicked.IsAlreadyBound(this, &ThisClass::OnReturnToTitleButtonClicked))
	{
		ReturnToTitleButton.Get()->OnClicked.AddDynamic(this, &ThisClass::OnReturnToTitleButtonClicked);
	}
}

void UUW_GameResult::OnReturnToTitleButtonClicked()
{
	UGameplayStatics::OpenLevel(GetWorld(), FName(TEXT("Title")), true);
}

 

 

4. 플레이어 강제 추방


PlayerController에 Client RPC를 통해서 Title로 돌아가는 함수 구현

void ADXPlayerController::ClientRPCReturnToTitle_Implementation()
{
	//only client's level change
	if (IsLocalController())
	{
		UGameplayStatics::OpenLevel(GetWorld(), FName(TEXT("Title")), true);
	}
}

 

이후 GameMode에서 일정 시간 이후 해당 함수가 호출되도록 구현

  • 참고) 타이머의 Invalidate() 함수를 통해 타이머를 무효화
case EMatchState::Enging:
{
	FString NotificationString = FString::Printf(TEXT("Waiting %d for returning to title."), RemainWaitingTimeForEnding);
	NotifyToAllPlayer(NotificationString);

	--RemainWaitingTimeForEnding;

	if (RemainWaitingTimeForEnding <= 0)
	{
		for (auto AliveController : AlivePlayerControllers)
		{
			AliveController->ClientRPCReturnToTitle();
		}

		for (auto DeadController : DeadPlayerControllers)
		{
			DeadController->ClientRPCReturnToTitle();
		}
		MainTimerHandle.Invalidate();
		return;
	}
	break;
}

 

버튼과 타이머로 로비로 추방하는 모습

 

 

5. 서버 초기화


 

 

 

'Unreal Engine' 카테고리의 다른 글

Unreal Engine - 데디케이티드 서버 8 (게임 흐름)  (0) 2025.05.02
Unreal Engine - AI (2)  (0) 2025.04.29
Unreal Engine - AI (1)  (1) 2025.04.25
Unreal Engine - 멀티플레이 네트워크 최적화 2  (0) 2025.04.23
Unreal Engine - 멀티플레이 네트워크 최적화 1  (0) 2025.04.22
'Unreal Engine' 카테고리의 다른 글
  • Unreal Engine - 데디케이티드 서버 8 (게임 흐름)
  • Unreal Engine - AI (2)
  • Unreal Engine - AI (1)
  • Unreal Engine - 멀티플레이 네트워크 최적화 2
gbleem
gbleem
gbleem 님의 블로그 입니다.
  • gbleem
    gbleem 님의 블로그
    gbleem
  • 전체
    오늘
    어제
    • 분류 전체보기 (176)
      • Unreal Engine (66)
      • C++ (19)
      • 알고리즘(코딩테스트) (26)
      • TIL (60)
      • CS (4)
      • 툴 (1)
  • 블로그 메뉴

    • 홈
    • 카테고리
  • 링크

    • 과제용 깃허브
    • 깃허브
    • velog
  • 공지사항

  • 인기 글

  • 태그

    const
    C++
    motion matching
    cin함수
    Vector
    BFS
    blend pose
    상속
    addonscreendebugmessage
    actor 클래스
    매크로 지정자
    map을 vector로 복사
    gamestate
    character animation
    DP
    applydamage
    템플릿
    enhanced input system
    additive animation
    싱글턴
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
gbleem
Unreal Engine - 데디케이티드 서버 9 (게임 종료)
상단으로

티스토리툴바