다양한 기록

[Unreal Network] GameMode & Login 본문

언리얼 엔진/Unreal Network Framework

[Unreal Network] GameMode & Login

라구넹 2025. 1. 15. 22:23

네트워크 모드와 서버 타입

스탠드얼론: 게임이 원격 클라이언트에 연결을 허용하지 않음

클라이언트: 프록시만 보여줌

리슨 서버: 게임이 서버 역할까지

데디케이티드 서버: 로컬 플레이어는 없이 서버로 동작

 

서버의 초기화

1. 스탠드얼론 상태

스탠드얼론이나 서버는 게임 모드 액터를 소유함

2. 플레이어 컨트롤러 0

리슨 서버는 일단 자신도 게임에 참여해야 함

-> 여기까지 하면 네트워크 기능을 켜고 게임 서비스를 시작하면 됨

=> 스탠드얼론에서 리슨서버로 변경

 

3. 클라이언트의 접속 요청

서버에는 플레이어 컨트롤러 1 생김

클라이언트를 대표하는 플레이어 컨트롤러는 클라이언트에 복제되는데,

클라이언트 내부에선 플레이어 컨트롤러 0 임

 

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"

#define LOG_CALLINFO ANSI_TO_TCHAR(__FUNCTION__)
#define AB_LOG(LogCat, Verbosity, Format, ...) UE_LOG(LogCat, Verbosity, TEXT("%s %s"), LOG_CALLINFO, *FString::Printf(Format, ##__VA_ARGS__))

DECLARE_LOG_CATEGORY_EXTERN(LogABNetwork, Log, All);
// Copyright Epic Games, Inc. All Rights Reserved.

#include "ArenaBattle.h"
#include "Modules/ModuleManager.h"

DEFINE_LOG_CATEGORY(LogABNetwork);
IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, ArenaBattle, "ArenaBattle" );

로그 선언 및 어느 클래스에서 발생한 로그인지까지 알게 설정

 

이런식으로 나옴

 

PreLogin : 클라이언트의 접속 요청을 처리하는 함수

Login : 접속을 허용한 클라이언트에 대응하는 플레이어 컨트롤러를 만드는 함수

PostLogin : 플레이어 입장을 위해 필요한 기본 설정을 모두 마무리하는 함수

StartLogin : 게임의 시작을 지시하는 함수

BeginPlay : 게임 모드의 StartPlay를 통해 게임이 시작될 때 모든 액터에서 호출하는 함수

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


#include "Game/ABGameMode.h"
#include "ArenaBattle/ArenaBattle.h"
#include "Player/ABPlayerController.h"

AABGameMode::AABGameMode()
{
	static ConstructorHelpers::FClassFinder<APawn> DefaultPawnClassRef(TEXT("/Script/Engine.Blueprint'/Game/ArenaBattle/Blueprint/BP_ABCharacterPlayer.BP_ABCharacterPlayer_C'"));
	if (DefaultPawnClassRef.Class)
	{
		DefaultPawnClass = DefaultPawnClassRef.Class;
	}

	static ConstructorHelpers::FClassFinder<APlayerController> PlayerControllerClassRef(TEXT("/Script/ArenaBattle.ABPlayerController"));
	if (PlayerControllerClassRef.Class)
	{
		PlayerControllerClass = PlayerControllerClassRef.Class;
	}
}

void AABGameMode::OnPlayerDead()
{

}

void AABGameMode::PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage)
{
	AB_LOG(LogABNetwork, Log, TEXT("Begin"));
	Super::PreLogin(Options, Address, UniqueId, ErrorMessage);
	AB_LOG(LogABNetwork, Log, TEXT("End"));
}

APlayerController* AABGameMode::Login(UPlayer* NewPlayer, ENetRole InRemoteRole, const FString& Portal, const FString& Options, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage)
{
	AB_LOG(LogABNetwork, Log, TEXT("Begin"));
	APlayerController* NewPlayerController = Super::Login(NewPlayer, InRemoteRole, Portal, Options, UniqueId, ErrorMessage);
	AB_LOG(LogABNetwork, Log, TEXT("End"));
	return NewPlayerController;
}

void AABGameMode::PostLogin(APlayerController* NewPlayer)
{
	AB_LOG(LogABNetwork, Log, TEXT("Begin"));
	Super::PostLogin(NewPlayer);
	AB_LOG(LogABNetwork, Log, TEXT("End"));
}

void AABGameMode::StartPlay()
{
	AB_LOG(LogABNetwork, Log, TEXT("Begin"));
	Super::StartPlay();
	AB_LOG(LogABNetwork, Log, TEXT("End"));
}

 

서버에서 가동해서 PreLogin은 안불림

StartPlay에 의해 모든 액터가 활성화

 

클라이언트 추가하니 PreLogin 불림

근데 중간에 컨트롤러 Begin Play 여러 번 불리는 거 확인 필요

 

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"

#define LOG_NETMODEINFO ((GetNetMode() == ENetMode::NM_Client) ? *FString::Printf(TEXT("CLIENT%d"), GPlayInEditorID) : ((GetNetMode() == ENetMode::NM_Standalone) ? TEXT("STANDALONE") : TEXT("SERVER"))) 
#define LOG_CALLINFO ANSI_TO_TCHAR(__FUNCTION__)
#define AB_LOG(LogCat, Verbosity, Format, ...) UE_LOG(LogCat, Verbosity, TEXT("[%s] %s %s"), LOG_NETMODEINFO, LOG_CALLINFO, *FString::Printf(Format, ##__VA_ARGS__))

DECLARE_LOG_CATEGORY_EXTERN(LogABNetwork, Log, All);

로그 업그레이드

 

클라이언트 추가 시 로그인이 어떻게 이루어지는지 확인 가능

 

서버에서  StartPlay 이후에는 알아서 BeginPlay가 알아서 호출됨

그럼 클라이언트에 있는 액터는 어떻게 신호를 받는가?

=> 서버는 Game State 라는 특별한 액터 사용, 게임 정보를 알려주는 액터

게임 스테이트는 서버와 클라이언트에 모두 존재

게임 모드가 게임 스테이트에 간접적으로 지시를 내림

명령을 받은 게임 스테이트는 월드의 모든 액터들에게 BeginPlay를 호출하도록 함

 

게임스테이트의

HandleBeginPlay

-> StartPlay하면 게임 스테이트가 월드의 모든 액터들에게 BeginPlay하고 게임 시작 명령

서버에서만 실행

 

OnRep_ReplicatedHasBegunPlay

-> bReplicatedHasBegunPlay 라는 프로퍼티가 서버로부터 전송되어 감지되면 함수가 호출되고 클라이언트가 신호를 받음