기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
Amazon GameLift Servers Unreal Engine 프로젝트에 통합
Amazon GameLift Servers SDK for Unreal Engine을 게임 프로젝트에 통합하여 전체 서버 SDK 기능 세트에 액세스하는 방법을 알아봅니다.
도움말
더 빠른 배포를 위해 Unreal Engine용 Amazon GameLift Servers 독립 실행형 플러그인을 사용해 보세요. 최소한의 설정으로 게임 서버를 빠르게 배포할 수 있는 가이드 UI 워크플로를 제공하므로 게임 구성 요소를 실제로 사용해 볼 수 있습니다. Amazon GameLift ServersUnreal Engine용 플러그인을(를) 참조하세요.
추가 리소스:
Unreal용 서버 SDK 설치
GitHub
빌드 대상 및 모듈 규칙 설정
게임 프로젝트 파일을 수정하여에 사용할 빌드 구성 요소를 올바르게 생성합니다Amazon GameLift Servers.
클라이언트 및 서버 빌드 대상을 추가하려면:
-
게임 프로젝트의 코드 파일을 열고 파일
.../Games/
파일을 찾습니다. 예시:[your application name]
Source/[your application name]
Target.cs.../Source/GameLiftUnrealAppTarget.cs
. (Visual Studio를 사용하는 경우 프로젝트의.sln
파일을 엽니다.) -
이 파일을 복사하여
Source/
디렉터리에 두 개의 새 대상 파일을 생성합니다.클라이언트 대상 - 새 파일의 이름을 로 변경합니다
. 다음 샘플 코드와 같이 콘텐츠를 편집하여 클래스 이름과 대상 유형 값을 업데이트합니다.[your application name]
Client.Target.csusing UnrealBuildTool; using System.Collections.Generic; public class GameLiftUnrealAppClientTarget : TargetRules { public GameLiftUnrealAppClientTarget ( TargetInfo Target ) : base ( Target ) { Type = TargetType.Client; DefaultBuildSettings = BuildSettingsVersion.V2; IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1; ExtraModuleNames.Add( "GameLiftUnrealApp"); } }
-
서버 대상 - 새 파일의 이름을 로 변경합니다
. 다음 샘플 코드와 같이 콘텐츠를 편집하여 클래스 이름과 대상 유형 값을 업데이트합니다.[your application name]
Server.Target.csusing UnrealBuildTool; using System.Collections.Generic; public class GameLiftUnrealAppServerTarget : TargetRules { public GameLiftUnrealAppServerTarget ( TargetInfo Target ) : base ( Target ) { Type = TargetType.Server; DefaultBuildSettings = BuildSettingsVersion.V2; IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_1; ExtraModuleNames.Add( "GameLiftUnrealApp"); } }
-
프로젝트 파일을 다시 생성합니다. Visual Studio를 사용하는 경우 게임 프로젝트의
.uproject
파일을 마우스 오른쪽 버튼으로 클릭하고 Visual Studio 프로젝트 파일 생성을 선택할 수 있습니다.
게임 프로젝트 모듈 규칙을 업데이트하려면:
플러그인에 종속되도록 게임 프로젝트의 모듈 규칙을 업데이트합니다.
-
게임 프로젝트의 코드 파일을 열고 파일
.../Games/
파일을 찾습니다. 예시:[your application name]
Source/[your application name]
.Build.cs.../Source/GameLiftUnrealApp.Build.cs
. (Visual Studio를 사용하는 경우 프로젝트의.sln
파일을 엽니다.) -
클래스를 찾고 다음 샘플 코드에 표시된 대로
ModuleRules
업데이트합니다.using UnrealBuildTool; public class GameLiftUnrealApp : ModuleRules { public GameLiftUnrealApp ( ReadOnlyTargetRules Target ) : base ( Target ) { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange( new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "EnhancedInput", "GameLiftServerSDK" }); bEnableExceptions = true; } }
새 대상 파일을 생성하고 모듈 규칙을 수정한 후 게임 프로젝트를 다시 빌드합니다.
서버 코드에 게임 호스팅 기능 추가
서버 SDK 설치 및 설정 후 다음 단계는 게임 호스팅 기능을 서버 코드에 통합하는 것입니다. 서버 SDK를 사용하면 게임 서버가 Amazon GameLift Servers 서비스와 통신하고, 게임 세션에 대한 지침을 수신하고, 상태 및 상태를 보고하고, 기타 작업을 수행할 수 있습니다.
이 주제에서는를 사용하여 게임을 호스팅하는 데 필요한 최소 기능을 추가하는 샘플 코드를 제공합니다Amazon GameLift Servers.
1단계: GameMode
헤더 파일 업데이트
-
게임 프로젝트의 코드 파일을 열고 파일
파일을 찾습니다. 예시:Your-application-name
GameMode.hGameLiftUnrealAppGameMode.h
. Visual Studio를 사용하는 경우 게임 프로젝트의.sln
파일을 엽니다. -
다음 예제 코드를 포함하도록 헤더 파일을 변경합니다. 반드시 “GameLiftUnrealApp”을 사용자 고유의 애플리케이션 이름으로 변경해야 합니다.
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 #pragma once #include "CoreMinimal.h" #include "GameFramework/GameModeBase.h" #include "GameLiftUnrealAppGameMode.generated.h" struct FProcessParameters; DECLARE_LOG_CATEGORY_EXTERN(GameServerLog, Log, All); UCLASS(minimalapi) class AGameLiftUnrealAppGameMode : public AGameModeBase { GENERATED_BODY() public: AGameLiftUnrealAppGameMode(); protected: virtual void BeginPlay() override; private: void InitGameLift(); private: TSharedPtr<FProcessParameters> ProcessParameters; };
2단계: 게임 서버 코드에 필요한 서버 SDK 호출 추가
이 섹션의 샘플 코드를 사용하여에 사용할 게임 서버 코드를 통합합니다Amazon GameLift Servers. 코드의 기능에 대한 자세한 내용은 서버 프로세스 초기화 및 단원을 참조하십시오용 C++(Unreal) 서버 SDK 5.x Amazon GameLift Servers -- 작업.
참고
WITH_GAMELIFT
프리프로세서 플래그는 다음 두 가지 용도로 사용됩니다.
Amazon GameLift Servers 백엔드 API 호출을 Unreal 서버 빌드로만 제한합니다.
다양한 Unreal 빌드 대상 간의 호환성 보장
-
관련 소스 파일인
파일을 엽니다. 이 예제에서는 입니다Your-application-name
GameMode.cppGameLiftUnrealAppGameMode.cpp
. 코드를 다음 예제 코드에 맞게 변경합니다. "GameLiftUnrealApp" 인스턴스를 고유한 애플리케이션 이름으로 바꿔야 합니다.
제공된 코드 샘플은 와의 통합에 필요한 요소를 추가하는 방법을 보여줍니다Amazon GameLift Servers. 다음이 포함됩니다.
-
Amazon GameLift Servers API 클라이언트를 초기화합니다.
-
콜백 함수를 구현하여 ,
OnStartGameSession
OnProcessTerminate
및를 포함한 Amazon GameLift Servers 서비스의 요청에 응답합니다onHealthCheck
. -
게임 세션을 호스팅
ProcessReady()
할 준비가 되면를 호출하여 Amazon GameLift Servers 서비스에 알립니다.
-
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 #include "GameLiftUnrealAppGameMode.h" #include "UObject/ConstructorHelpers.h" #include "Kismet/GameplayStatics.h" #if WITH_GAMELIFT #include "GameLiftServerSDK.h" #include "GameLiftServerSDKModels.h" #endif #include "GenericPlatform/GenericPlatformOutputDevices.h" DEFINE_LOG_CATEGORY(GameServerLog); AGameLiftUnrealAppGameMode::AGameLiftUnrealAppGameMode() : ProcessParameters(nullptr) { // Set default pawn class to our Blueprinted character static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter")); if (PlayerPawnBPClass.Class != NULL) { DefaultPawnClass = PlayerPawnBPClass.Class; } UE_LOG(GameServerLog, Log, TEXT("Initializing AGameLiftUnrealAppGameMode...")); } void AGameLiftUnrealAppGameMode::BeginPlay() { Super::BeginPlay(); #if WITH_GAMELIFT InitGameLift(); #endif } void AGameLiftUnrealAppGameMode::InitGameLift() { #if WITH_GAMELIFT UE_LOG(GameServerLog, Log, TEXT("Calling InitGameLift...")); // Getting the module first. FGameLiftServerSDKModule* GameLiftSdkModule = &FModuleManager::LoadModuleChecked<FGameLiftServerSDKModule>(FName("GameLiftServerSDK")); //Define the server parameters for a GameLift Anywhere fleet. These are not needed for a GameLift managed EC2 fleet. FServerParameters ServerParametersForAnywhere; bool bIsAnywhereActive = false; if (FParse::Param(FCommandLine::Get(), TEXT("glAnywhere"))) { bIsAnywhereActive = true; } if (bIsAnywhereActive) { UE_LOG(GameServerLog, Log, TEXT("Configuring server parameters for Anywhere...")); // If GameLift Anywhere is enabled, parse command line arguments and pass them in the ServerParameters object. FString glAnywhereWebSocketUrl = ""; if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereWebSocketUrl="), glAnywhereWebSocketUrl)) { ServerParametersForAnywhere.m_webSocketUrl = TCHAR_TO_UTF8(*glAnywhereWebSocketUrl); } FString glAnywhereFleetId = ""; if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereFleetId="), glAnywhereFleetId)) { ServerParametersForAnywhere.m_fleetId = TCHAR_TO_UTF8(*glAnywhereFleetId); } FString glAnywhereProcessId = ""; if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereProcessId="), glAnywhereProcessId)) { ServerParametersForAnywhere.m_processId = TCHAR_TO_UTF8(*glAnywhereProcessId); } else { // If no ProcessId is passed as a command line argument, generate a randomized unique string. FString TimeString = FString::FromInt(std::time(nullptr)); FString ProcessId = "ProcessId_" + TimeString; ServerParametersForAnywhere.m_processId = TCHAR_TO_UTF8(*ProcessId); } FString glAnywhereHostId = ""; if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereHostId="), glAnywhereHostId)) { ServerParametersForAnywhere.m_hostId = TCHAR_TO_UTF8(*glAnywhereHostId); } FString glAnywhereAuthToken = ""; if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereAuthToken="), glAnywhereAuthToken)) { ServerParametersForAnywhere.m_authToken = TCHAR_TO_UTF8(*glAnywhereAuthToken); } FString glAnywhereAwsRegion = ""; if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereAwsRegion="), glAnywhereAwsRegion)) { ServerParametersForAnywhere.m_awsRegion = TCHAR_TO_UTF8(*glAnywhereAwsRegion); } FString glAnywhereAccessKey = ""; if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereAccessKey="), glAnywhereAccessKey)) { ServerParametersForAnywhere.m_accessKey = TCHAR_TO_UTF8(*glAnywhereAccessKey); } FString glAnywhereSecretKey = ""; if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereSecretKey="), glAnywhereSecretKey)) { ServerParametersForAnywhere.m_secretKey = TCHAR_TO_UTF8(*glAnywhereSecretKey); } FString glAnywhereSessionToken = ""; if (FParse::Value(FCommandLine::Get(), TEXT("glAnywhereSessionToken="), glAnywhereSessionToken)) { ServerParametersForAnywhere.m_sessionToken = TCHAR_TO_UTF8(*glAnywhereSessionToken); } UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_YELLOW); UE_LOG(GameServerLog, Log, TEXT(">>>> WebSocket URL: %s"), *ServerParametersForAnywhere.m_webSocketUrl); UE_LOG(GameServerLog, Log, TEXT(">>>> Fleet ID: %s"), *ServerParametersForAnywhere.m_fleetId); UE_LOG(GameServerLog, Log, TEXT(">>>> Process ID: %s"), *ServerParametersForAnywhere.m_processId); UE_LOG(GameServerLog, Log, TEXT(">>>> Host ID (Compute Name): %s"), *ServerParametersForAnywhere.m_hostId); UE_LOG(GameServerLog, Log, TEXT(">>>> Auth Token: %s"), *ServerParametersForAnywhere.m_authToken); UE_LOG(GameServerLog, Log, TEXT(">>>> Aws Region: %s"), *ServerParametersForAnywhere.m_awsRegion); UE_LOG(GameServerLog, Log, TEXT(">>>> Access Key: %s"), *ServerParametersForAnywhere.m_accessKey); UE_LOG(GameServerLog, Log, TEXT(">>>> Secret Key: %s"), *ServerParametersForAnywhere.m_secretKey); UE_LOG(GameServerLog, Log, TEXT(">>>> Session Token: %s"), *ServerParametersForAnywhere.m_sessionToken); UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_NONE); } UE_LOG(GameServerLog, Log, TEXT("Initializing the GameLift Server...")); //InitSDK will establish a local connection with GameLift's agent to enable further communication. FGameLiftGenericOutcome InitSdkOutcome = GameLiftSdkModule->InitSDK(ServerParametersForAnywhere); if (InitSdkOutcome.IsSuccess()) { UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_GREEN); UE_LOG(GameServerLog, Log, TEXT("GameLift InitSDK succeeded!")); UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_NONE); } else { UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_RED); UE_LOG(GameServerLog, Log, TEXT("ERROR: InitSDK failed : (")); FGameLiftError GameLiftError = InitSdkOutcome.GetError(); UE_LOG(GameServerLog, Log, TEXT("ERROR: %s"), *GameLiftError.m_errorMessage); UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_NONE); return; } ProcessParameters = MakeShared<FProcessParameters>(); //When a game session is created, Amazon GameLift Servers sends an activation request to the game server and passes along the game session object containing game properties and other settings. //Here is where a game server should take action based on the game session object. //Once the game server is ready to receive incoming player connections, it should invoke GameLiftServerAPI.ActivateGameSession() ProcessParameters->OnStartGameSession.BindLambda([=](Aws::GameLift::Server::Model::GameSession InGameSession) { FString GameSessionId = FString(InGameSession.GetGameSessionId()); UE_LOG(GameServerLog, Log, TEXT("GameSession Initializing: %s"), *GameSessionId); GameLiftSdkModule->ActivateGameSession(); }); //OnProcessTerminate callback. Amazon GameLift Servers will invoke this callback before shutting down an instance hosting this game server. //It gives this game server a chance to save its state, communicate with services, etc., before being shut down. //In this case, we simply tell Amazon GameLift Servers we are indeed going to shutdown. ProcessParameters->OnTerminate.BindLambda([=]() { UE_LOG(GameServerLog, Log, TEXT("Game Server Process is terminating")); GameLiftSdkModule->ProcessEnding(); }); //This is the HealthCheck callback. //Amazon GameLift Servers will invoke this callback every 60 seconds or so. //Here, a game server might want to check the health of dependencies and such. //Simply return true if healthy, false otherwise. //The game server has 60 seconds to respond with its health status. Amazon GameLift Servers will default to 'false' if the game server doesn't respond in time. //In this case, we're always healthy! ProcessParameters->OnHealthCheck.BindLambda([]() { UE_LOG(GameServerLog, Log, TEXT("Performing Health Check")); return true; }); //GameServer.exe -port=7777 LOG=server.mylog ProcessParameters->port = FURL::UrlConfig.DefaultPort; TArray<FString> CommandLineTokens; TArray<FString> CommandLineSwitches; FCommandLine::Parse(FCommandLine::Get(), CommandLineTokens, CommandLineSwitches); for (FString SwitchStr : CommandLineSwitches) { FString Key; FString Value; if (SwitchStr.Split("=", &Key, &Value)) { if (Key.Equals("port")) { ProcessParameters->port = FCString::Atoi(*Value); } } } //Here, the game server tells Amazon GameLift Servers where to find game session log files. //At the end of a game session, Amazon GameLift Servers uploads everything in the specified //location and stores it in the cloud for access later. TArray<FString> Logfiles; Logfiles.Add(TEXT("GameServerLog/Saved/Logs/GameServerLog.log")); ProcessParameters->logParameters = Logfiles; //The game server calls ProcessReady() to tell Amazon GameLift Servers it's ready to host game sessions. UE_LOG(GameServerLog, Log, TEXT("Calling Process Ready...")); FGameLiftGenericOutcome ProcessReadyOutcome = GameLiftSdkModule->ProcessReady(*ProcessParameters); if (ProcessReadyOutcome.IsSuccess()) { UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_GREEN); UE_LOG(GameServerLog, Log, TEXT("Process Ready!")); UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_NONE); } else { UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_RED); UE_LOG(GameServerLog, Log, TEXT("ERROR: Process Ready Failed!")); FGameLiftError ProcessReadyError = ProcessReadyOutcome.GetError(); UE_LOG(GameServerLog, Log, TEXT("ERROR: %s"), *ProcessReadyError.m_errorMessage); UE_LOG(GameServerLog, SetColor, TEXT("%s"), COLOR_NONE); } UE_LOG(GameServerLog, Log, TEXT("InitGameLift completed!")); #endif }
3단계: 게임 프로젝트 재구축
-
Development Editor 및 개발 서버 대상 유형 모두를 위한 게임 프로젝트를 빌드합니다.
참고
솔루션을 다시 빌드할 필요는 없습니다. 대신 앱의
/Games/
폴더 아래에 프로젝트를 빌드합니다. 그렇지 않으면 Visual Studio가 전체 UE5 프로젝트를 다시 빌드하므로 최대 1시간이 걸릴 수 있습니다.
호스팅을 위해 게임 서버 패키징
이제 게임 서버 코드가 최소 필수 서버 SDK 기능과 통합되어 Unreal Editor를 사용하여 게임 서버 빌드를 패키징할 준비가 되었습니다.
게임 서버 빌드를 패키징하려면
-
Unreal Editor에서 게임 프로젝트를 엽니다.
-
Unreal Editor 단계에 따라 게임 서버를 패키징합니다.
-
대상 플랫폼(Windows 또는 Linux)을 선택합니다.
-
서버 빌드 대상(
.[your application name]
Server
패키징 프로세스는 게임 서버 실행 파일을 생성합니다
.[your application name]
Server.exe -
-
호스팅 리소스에 배포할 게임 서버 빌드를 준비합니다. 빌드에는 다음 파일이 포함되어야 합니다.
-
게임 서버 실행 파일
-
Windows 빌드의 경우 다음 파일을 포함합니다(Unreal Engine의 소스 빌드 버전에서 찾을 수 있음).
-
VC_redist.x64.exe
(UnrealEngine\Engine\Source\Programs\PrereqInstaller\Resources\VCRedist\
) -
UEPrereqSetup_x64.exe or UE5PrereqSetup_x64.exe
(UnrealEngine\Engine\Extras\Redist\en-us\
)
-
-
게임 서버에 필요한 기타 모든 종속성입니다.
-
필요한 경우 OpenSSL 라이브러리. 게임 서버 빌드와 통합된 서버 SDK 버전을 확인합니다. Unreal용 서버 SDK 버전 5.3.x를 사용하면 더 이상 게임 서버 빌드에 OpenSSL 라이브러리를 수동으로 포함할 필요가 없습니다. 모든 이전 버전의 경우 라이브러리 파일을 찾아 추가해야 합니다. 최신 서버 SDK 버전을 참조하세요.
-
게임 서버를 Unreal로 패키징할 때 사용한 것과 동일한 버전의 OpenSSL 라이브러리를 포함해야 합니다. 이러한 라이브러리는 게임 엔진 소스에 있습니다. 위치는 개발 환경에 따라 다릅니다.
Windows의 경우:
-
[ENGINE_ROOT_DIR]\Engine\Extras\ThirdPartyNotUE\libimobiledevice\x64\libssl-1_1-x64.dll
-
[ENGINE_ROOT_DIR]\Engine\Extras\ThirdPartyNotUE\libimobiledevice\x64\libcrypto-1_1-x64.dll
Linux의 경우:
-
Engine/Source/Thirdparty/OpenSSL/1.1.1n/include/libssl.so.1.1
-
Engine/Source/Thirdparty/OpenSSL/1.1.1n/include/libcrypto.so.1.1
OpenSSL 라이브러리를 게임 서버 실행 파일과 동일한 디렉터리의 게임 빌드 패키지에 복사합니다.
다음 단계
이제를 사용하여 호스팅하는 데 필요한 최소 기능으로 게임 서버 빌드를 준비했으므로 다음과 같은 잠재적 다음 단계를 Amazon GameLift Servers고려하세요.
및 테스트 및 개발을 위해 통합 게임 서버를 배포합니다. Anywhere 플릿을 사용하면 로컬 시스템을 호스팅 리소스로 설정하고 이를 사용하여 게임 서버 및 게임 클라이언트 연결을 테스트할 수 있습니다. 클라우드 기반 호스팅의 경우 관리형 EC2 또는 관리형 컨테이너 플릿에 게임 서버를 배포합니다. 지침은 다음 주제를 참조하세요.
선택적 기능을 추가하여 게임 서버 통합을 사용자 지정합니다. 예를 들어 고유한 플레이어 IDs로 플레이어 세션을 추가하거나, 매치메이킹 채우기를 설정하거나, 다른 AWS 리소스(예: 데이터베이스 또는 콘텐츠 스토리지 서비스)에 대한 게임 서버 액세스를 관리할 수 있습니다. 지침은 다음 주제를 참조하세요.
게임 클라이언트 구성 요소를 사용자 지정하여 게임 세션을 요청하고, 연결 정보를 수신하고, 게임 서버에 직접 연결하여 게임을 플레이합니다. 지침은 다음 주제를 참조하세요.