View a markdown version of this page

Plugin pour Unreal : intégrez le code de votre jeu - GameLift Serveurs Amazon

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Plugin pour Unreal : intégrez le code de votre jeu

Avant de pouvoir déployer votre serveur de jeu sur une flotte, vous devez effectuer une série de mises à jour du code du jeu et empaqueter les composants du jeu à utiliser avec le Amazon GameLift Servers service.

Cette rubrique décrit les étapes à suivre pour effectuer une intégration minimale. Pour l'intégration au serveur, utilisez l'exemple de code fourni pour mettre à jour le mode de jeu de votre projet.

Configurer les cibles de construction et les règles du module

Modifiez les fichiers de votre projet de jeu pour générer correctement les composants de construction à utiliser avecAmazon GameLift Servers.

Pour ajouter des cibles de génération de clients et de serveurs, procédez comme suit :
  1. Ouvrez les fichiers de code de votre projet de jeu et localisez le .../Games/[your application name]Source/[your application name]Target.cs fichier. Exemple: .../Source/GameLiftUnrealAppTarget.cs. (Si vous utilisez Visual Studio, ouvrez le .sln fichier du projet.)

  2. Copiez ce fichier pour créer deux nouveaux fichiers cibles dans le Source/ répertoire.

    • Cible du client : renommez le nouveau fichier en[your application name]Client.Target.cs. Modifiez le contenu pour mettre à jour le nom de la classe et les valeurs du type de cible, comme illustré dans l'exemple de code suivant :

      using 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"); } }
    • Cible du serveur : renommez le nouveau fichier en[your application name]Server.Target.cs. Modifiez le contenu pour mettre à jour le nom de la classe et les valeurs du type de cible, comme illustré dans l'exemple de code suivant :

      using 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"); } }
  3. Régénérez vos fichiers de projet. Si vous utilisez Visual Studio, vous pouvez cliquer avec le bouton droit sur le .uproject fichier de votre projet de jeu et sélectionner Générer des fichiers de projet Visual Studio.

Pour mettre à jour les règles du module de projet de jeu :

Mettez à jour les règles du module du projet de jeu pour les rendre dépendantes du plugin.

  1. Ouvrez les fichiers de code de votre projet de jeu et localisez le .../Games/[your application name]Source/[your application name].Build.cs fichier. Exemple: .../Source/GameLiftUnrealApp.Build.cs. (Si vous utilisez Visual Studio, ouvrez le .sln fichier du projet.)

  2. Localisez la ModuleRules classe et mettez-la à jour comme illustré dans l'exemple de code suivant :

    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" }); // Add the following section if (Target.Type == TargetType.Server) { PublicDependencyModuleNames.Add("GameLiftServerSDK"); } else { PublicDefinitions.Add("WITH_GAMELIFT=0"); } bEnableExceptions = true; } }
  3. Après avoir créé les nouveaux fichiers cibles et modifié les règles du module, reconstruisez votre projet de jeu.

Mettez à jour le code de votre serveur de jeu

Mettez à jour le code de votre serveur de jeu pour permettre la communication entre un processus du serveur de jeu et le Amazon GameLift Servers service. Votre serveur de jeu doit être en mesure de répondre aux demandes émanantAmazon GameLift Servers, par exemple, de démarrer et d'arrêter de nouvelles sessions de jeu.

Pour ajouter du code de serveur pour GameLift Serveurs Amazon
  1. Dans votre éditeur de code, ouvrez le fichier solution (.sln) de votre projet de jeu, qui se trouve généralement dans le dossier racine du projet. Par exemple : GameLiftUnrealApp.sln.

  2. Avec la solution ouverte, localisez le fichier d'en-tête du mode de jeu du projet : [project-name]GameMode.h file. Par exemple : GameLiftUnrealAppGameMode.h.

  3. Modifiez le fichier d'en-tête pour l'aligner sur le code suivant. Veillez à remplacer « GameLiftServer » par le nom de votre projet. Ces mises à jour sont spécifiques au serveur de jeu ; nous vous recommandons de créer une copie de sauvegarde des fichiers du mode de jeu d'origine pour les utiliser avec votre client.

// 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; };
  • Ouvrez le [project-name]GameMode.cpp fichier source correspondant (par exempleGameLiftUnrealAppGameMode.cpp). Modifiez le code pour l'aligner sur l'exemple de code suivant. Veillez à remplacer « GameLiftUnrealApp » par le nom de votre projet. Ces mises à jour sont spécifiques au serveur de jeu ; nous vous recommandons de créer une copie de sauvegarde du fichier d'origine pour l'utiliser avec votre client.

    L'exemple de code suivant montre comment ajouter le minimum d'éléments requis pour l'intégration du serveur avec Amazon GameLift Servers :

    • Initialisez un client Amazon GameLift Servers API. L'InitSDK()appel avec les paramètres du serveur est obligatoire pour une flotte Amazon GameLift Servers Anywhere. Lorsque vous vous connectez à une flotte Anywhere, le plug-in stocke les paramètres du serveur sous forme d'arguments de console. L'exemple de code peut accéder aux valeurs lors de l'exécution.

    • Implémentez les fonctions de rappel requises pour répondre aux demandes du Amazon GameLift Servers service, notamment OnStartGameSessionOnProcessTerminate, etonHealthCheck.

    • Appelez ProcessReady() via un port désigné pour avertir le Amazon GameLift Servers service lorsque vous êtes prêt à héberger des sessions de jeu.

// 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")); // First call ProcessEnding() FGameLiftGenericOutcome processEndingOutcome = GameLiftSdkModule->ProcessEnding(); // Then call Destroy() to free the SDK from memory FGameLiftGenericOutcome destroyOutcome = GameLiftSdkModule->Destroy(); // Exit the process with success or failure if (processEndingOutcome.IsSuccess() && destroyOutcome.IsSuccess()) { UE_LOG(GameServerLog, Log, TEXT("Server process ending successfully")); } else { if (!processEndingOutcome.IsSuccess()) { const FGameLiftError& error = processEndingOutcome.GetError(); UE_LOG(GameServerLog, Error, TEXT("ProcessEnding() failed. Error: %s"), error.m_errorMessage.IsEmpty() ? TEXT("Unknown error") : *error.m_errorMessage); } if (!destroyOutcome.IsSuccess()) { const FGameLiftError& error = destroyOutcome.GetError(); UE_LOG(GameServerLog, Error, TEXT("Destroy() failed. Error: %s"), error.m_errorMessage.IsEmpty() ? TEXT("Unknown error") : *error.m_errorMessage); } } }); //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("GameLiftUnrealApp/Saved/Logs/server.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 }

Intégrez la carte de jeu de votre client

La carte du jeu de démarrage contient une logique de base et des éléments d'interface utilisateur qui incluent déjà du code de base pour demander des sessions de jeu et utiliser les informations de connexion pour se connecter à une session de jeu. Vous pouvez utiliser la carte telle quelle ou la modifier selon vos besoins. Utilisez la carte du jeu de démarrage avec d'autres éléments du jeu, tels que le modèle de projet Third Person fourni par Unreal Engine. Ces ressources sont disponibles dans le navigateur de contenu. Vous pouvez les utiliser pour tester les flux de déploiement du plugin, ou comme guide pour créer un service backend personnalisé pour votre jeu.

La carte de démarrage présente les caractéristiques suivantes :

  • Il inclut une logique à la fois pour une flotte Anywhere et pour une flotte EC2 gérée. Lorsque vous gérez votre client, vous pouvez choisir de vous connecter à l'une ou l'autre de vos flottes.

  • Les fonctionnalités du client incluent la recherche d'une session de jeu (SearchGameSessions()), la création d'une nouvelle session de jeu (CreateGameSession()) et la participation directe à une session de jeu.

  • Il obtient un identifiant de joueur unique à partir du groupe d'utilisateurs Amazon Cognito de votre projet (cela fait partie d'une solution Anywhere déployée).

Pour utiliser la carte du jeu de démarrage
  1. Dans l'éditeur UE, ouvrez la page Paramètres du projet, cartes et modes, puis développez la section Cartes par défaut.

  2. Pour la carte de démarrage de l'éditeur, sélectionnez StartupMap « » dans la liste déroulante. Il se peut que vous deviez rechercher le fichier qui se trouve dans... > Unreal Projects/[project-name]/Plugins/Amazon GameLift Servers Plugin Content/Maps.

    Note

    Pour trouver l'exemple de carte de démarrage, sélectionnez l'icône des paramètres et choisissez Afficher le contenu du plug-in.

  3. Pour la carte par défaut du jeu, sélectionnez le même StartupMap « » dans la liste déroulante.

  4. Pour la carte par défaut du serveur, sélectionnez « Lv1_ ThirdPerson » pour Unreal Engine 5.6 ou version ultérieure, ou « ThirdPersonMap » pour les versions antérieures. Il s'agit d'une carte par défaut incluse dans votre projet de jeu. Cette carte est conçue pour deux joueurs dans le jeu.

  5. Ouvrez le panneau de détails de la carte par défaut du serveur. Réglez GameMode Override sur « Aucun ».

  6. Développez la section Modes par défaut et définissez le mode de jeu global par défaut sur le mode de jeu que vous avez mis à jour pour l'intégration de votre serveur.

Une fois ces modifications apportées à votre projet, vous êtes prêt à créer les composants de votre jeu.

Note

Pour Unreal Engine 5.6 ou version ultérieure, si vous ne pouvez pas déplacer le personnage après vous être connecté au serveur de jeu, mettez à jour le ThirdPersonCharacter plan BP_ pour ajouter un contexte de mappage d'entrée pour IMC_Default et IMC_MouseLook comme indiqué ci-dessous :

Nœuds Blueprint montrant les nœuds Event BeginPlay connecté à Cast To PlayerController et Add Mapping Context pour IMC_default et IMC_. MouseLook

Emballez les composants de votre jeu

Pour empaqueter les versions de votre serveur de jeu et de votre client de jeu
  1. Ouvrez votre projet de jeu dans une version source de l'éditeur Unreal Engine.

  2. Si vous utilisez Unreal Engine 5.6 ou une version ultérieure, accédez à Edition, Paramètres du projet, Emballage. Trouvez Cook everything dans le répertoire de contenu du projet et activez-le.

  3. Utilisez l'éditeur pour empaqueter les versions de votre client de jeu et de votre serveur.

    1. Choisissez une cible. Accédez à Plateformes, Windows et sélectionnez l'une des options suivantes :

      • Serveur : [your-application-name]Server

      • Client :[your-application-name]Client

    2. Démarrez la construction. Accédez à Platform, Windows, Package Project.

Chaque processus d'empaquetage génère un exécutable : [your-application-name]Client.exe ou[your-application-name]Server.exe.

Dans le plug-in, définissez les chemins d'accès aux exécutables de génération du client et du serveur sur votre poste de travail local.