Skip to content Skip to sidebar Skip to footer

Need to Continue a Spawn After It is No Longer on the Screen Unreal Engine

Choose your operating system:

In your game projects, there may be times when the player character is destroyed through gameplay and you will want to respawn them back into the world.

In this How-To guide, you will learn how to set up a simple respawn system using the Third Person Template, for a single-player, non-replicated game. You will then be tasked with implementing functionality for the Game Mode class, which will respawn a third-person player character back into your Level.

image alt text

Choose your implementation method:

Project Setup

You will start by creating a new Third Person Template and setting up input mappings from the Project Settings. These input mappings will enable the respawn functionality that you will create for your Player Character.

  1. Begin by creating a new Games > Third Person > Blueprint project named RespawnPlayer.

    image alt text

  2. Navigate to Edit > Project Settings >Engine > Input, then from the Details panel�s Bindings category, click the Add (+) button next to the Action Mappings variable to create a new Action Mapping named Restart.

    image alt text

  3. Set the Restart Action Mapping key value to R.

    image alt text

Implementing the RespawnPlayerGameMode Class

In this example, the GameMode class is responsible for respawning the player character class when it is destroyed during gameplay. You will be tasked with implementing this functionality through the use of Event Dispatchers.

  1. From the Content Browser navigate to Content > ThirdPersonBP and double-click the ThirdPersonGameMode Blueprint to open its Class Defaults.

    image alt text

  2. In the Class Defaults , click the Open Full Blueprint Editor link.

    image alt text

  3. From the My Blueprint panel, navigate to the Event Dispatchers category and click the Add (+) button to create a new Event Dispatcher named OnPlayerDied.

    image alt text

  4. Navigate to the Details panel, then from the Inputs category click the Add (+) button to create a New Input Parameter of Blueprint class type Character, then name it Character.

    image alt text

  5. Right-click the Event Graph to bring up the Actions menu, then search for and select Event BeginPlay.

    image alt text

  6. From the Begin Play Node, drag from of the execution pin, then from the Actions menu, search for and select the Bind Event On Player Died node.

    image alt text

  7. Drag off the Event pin from the Bind Event to On Player Died node, then from the Actions menu, search for and select Add Custom Event, and name this custom event PlayerDied.

    image alt text

    You have created and bound an Event to a Custom Event with the intention of calling it from another Blueprint.

    This causes the Event in this Blueprint to trigger when the Event occurs within another Blueprint, such as the OnDestroy Event from the ThirdPersonCharacter Blueprint class. This is called an Event Dispatcher.

  8. From the PlayerDied Custom Event node, drag from the Character pin, and from the Actions dropdown menu search for and select the Get Controller node.

    image alt text

  9. From the PlayerDied node, drag from the execution pin, then from the Actions menu, search for and select the Restart Player function.

    image alt text

  10. Drag from the Return Value output pin from the Get Controller node, and connect it into the New Player input pin of the RestartPlayer node.

    image alt text

    RestartPlayer is a method that already exists within the GameModeBase class. It tries to spawn the player's Pawn at the location returned by FindPlayerStart.

  11. Click Compile and Save.

    image alt text

Finished Blueprint

image alt text

Implementing the RespawnPlayerCharacter Class

You will now be implementing the logic to destroy the RespawnPlayerCharacter and call the GameMode's RestartPlayer method.

  1. From the Content Browser navigate to Content > ThirdPersonBP and double-click the ThirdPersonCharacter to open its Class Defaults.

    image alt text

  2. From the My Blueprint panel, Navigate to the Functions category and click the Override button. Then, from the dropdown menu select the Destroyed Override Function.

    image alt text

    When selecting the Override button from the Functions category, each function lists the class from which the Character inherits its override. A Destroyed event is listed because the Character class inherits from the Actor class, which contains its own Destroyed function.

  3. Drag from the Event Destroyed execution pin and from the Actions menu, search for and select Cast to Third Person Game Mode.

    image alt text

  4. From the Cast to Third Person Game Mode node, drag from the Object pin, then search for and select the Get Game Mode node.

    image alt text

  5. From the Third Person Game Mode node, drag from the As Third Person Game mode pin, then search for and select the Call On Player Died event dispatcher.

    image alt text

  6. From the Call On Player Died node, drag from the Character pin and from the Actions menu search for and select Get a reference to self.

    image alt text

  7. From the My Blueprint tab, navigate to the Functions category and click the Add (+) button to create a new function named Call Restart Player.

    image alt text

  8. Double-click Call Restart Player, then navigate to the Local Variables category and click the Add (+) button to create a new local variable of type Controller, named ControllerRef.

    image alt text

  9. Drag the ControllerRef variable onto the Execution pin of the Call Restart Player node.

    image alt text

  10. Drag from the ControllerRef pin, and from the Actions menu, search for and select Get Controller from the Pawn category.

    image alt text

  11. Navigate back to the Set ControllerRef node, then drag from the execution pin and from the Actions menu search for and select DestroyActor.

    image alt text

  12. From the Destroy Actor node, drag from the execution pin, then from the Actions menu, search for and select Cast to Third Person Game Mode.

    image alt text

  13. From the Cast to Third Person Game Mode node, drag from the Object pin, then search for and select the Get Game Mode node.

    image alt text

  14. From the Third Person Game Mode node, drag from the As Third Person Game mode pin, then search for and select for RestartPlayer.

    image alt text

  15. From the My Blueprint panel, navigate to the Local Variables category, then drag a copy of your ControllerRef onto the New Player pin from the Restart Player node.

    image alt text

  16. Click Compile and Save.

    image alt text

    Your completed Call Restart Player function will appear as it does below.

    image alt text

  17. Navigate back to the Event Graph, then right-click, search for, and select the Restart Input Action Event.

    image alt text

  18. Drag off of the Pressed key pin, then from the Actions menu, search for and select Call Restart Player.

    image alt text

    The Call Restart Player function will destroy your player character and is triggered when the R key is pressed. The Destroy method will usually be triggered when the player loses enough health from a Gameplay event that would despawn your player.

  19. Click Compile and Save

    image alt text

Finished Blueprint

image alt text

End Result

Navigate back to the editor and click Play in Editor (PIE).

You can control your character's movement around the map by using the W, A, S, D keys.

When you press the R key your player character will disappear momentarily, then respawn at the Player Start Location.

image alt text

Project Setup

You will start by creating a new Third Person Template and setting up input mappings from the Project Settings. These input mappings will enable the respawn functionality that you will create for your Player Character.

  1. Begin by creating a new Games > Third Person > C++ project named RespawnPlayer.

    image alt text

  2. Navigate to Edit > Project Settings >Engine > Input, then from the Details panel's Bindings category, click the Add (+) button next to the Action Mappings variable to create a new Action Mapping named Restart.

    image alt text

  3. Set the Restart Action Mapping key value to R.

    image alt text

Implementing the RespawnPlayerGameMode Class

In this example, the GameMode class is responsible for respawning the player character class when the player character is destroyed during gameplay. You will be tasked with implementing this functionality through the use of Delegates.

  1. From the Content Browser, navigate to your C++ Classes folder and double-click the RespawnPlayerGameMode to open its RespawnPlayerGameMode.h.

    image alt text

  2. Inside the RespawnPlayerGameMode.h file, declare the following code under your library include declarations

                    DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerDiedSignature, ACharacter*, Character);              

    This action creates a Dynamic Multicast delegate FOnPlayerDiedSignature for your Game mode class to bind when your Player Character dies.

  3. Next, declare the following class declarations:

                    public:     const FOnPlayerDiedSignature& GetOnPlayerDied() const { returnOnPlayerDied; }      //Tries to Spawn the player's pawn.     virtual void RestartPlayer(AController* NewPlayer) override;  protected:     virtual void BeginPlay() override;      //Called when Player character has died.     UFUNCTION()     virtual void PlayerDied(ACharacter* Character);      //Signature to bind delegate.      UPROPERTY()     FOnPlayerDiedSignature OnPlayerDied;              

    RestartPlayer is a method that already exists within the GameModeBase class. It tries to spawn the player's Pawn at the location returned by FindPlayerStart.

  4. Navigate to your RespawnPlayerGameMode.cpp file and implement the following class methods

                    void ARespawnPlayerGameMode::BeginPlay() {     Super::BeginPlay();      //Bind our Player died delegate to the Gamemode's PlayerDied function.     if (!OnPlayerDied.IsBound())     {         OnPlayerDied.AddDynamic(this, &ARespawnPlayerGameMode::PlayerDied);     }  }  void ARespawnPlayerGameMode::RestartPlayer(AController* NewPlayer) {     Super::RestartPlayer(NewPlayer); }  void ARespawnPlayerGameMode::PlayerDied(ACharacter* Character) {     //Get a reference to our Character's Player Controller     AController* CharacterController = Character->GetController();     RestartPlayer(CharacterController); }              
  5. Compile your code.

Finished Code

RespawnPlayerGameMode.h

            // Copyright Epic Games, Inc. All Rights Reserved. #pragma once  #include "CoreMinimal.h" #include "GameFramework/GameModeBase.h" #include "RespawnPlayerGameMode.generated.h"  DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerDiedSignature, ACharacter*, Character);  UCLASS(minimalapi)  class ARespawnPlayerGameMode : public AGameModeBase {     GENERATED_BODY()  public:      ARespawnPlayerGameMode();      const FOnPlayerDiedSignature& GetOnPlayerDied() const { return OnPlayerDied; }  //Tries to Spawn the player's pawn. virtual void RestartPlayer(AController* NewPlayer) override;  protected:      virtual void BeginPlay() override;      //Called when Player character has died.     UFUNCTION()     virtual void PlayerDied(ACharacter* Character);      //Signature to bind delegate.      UPROPERTY()     FOnPlayerDiedSignature OnPlayerDied; };          

RespawnPlayerGameMode.cpp

            #include "RespawnPlayerGameMode.h" #include "RespawnPlayerCharacter.h" #include "UObject/ConstructorHelpers.h"  ARespawnPlayerGameMode::ARespawnPlayerGameMode() {     // set default pawn class to our Blueprinted character     static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/ThirdPersonCPP/Blueprints/ThirdPersonCharacter"));     if (PlayerPawnBPClass.Class != NULL)     {         DefaultPawnClass = PlayerPawnBPClass.Class;     } }  void ARespawnPlayerGameMode::BeginPlay() {     Super::BeginPlay();      //Bind our Player died delegate to the Gamemode's PlayerDied function.     if (!OnPlayerDied.IsBound())     {         OnPlayerDied.AddDynamic(this, &ARespawnPlayerGameMode::PlayerDied);     }  }  void ARespawnPlayerGameMode::RestartPlayer(AController* NewPlayer) {     Super::RestartPlayer(NewPlayer); }  void ARespawnPlayerGameMode::PlayerDied(ACharacter* Character) {     //Get a reference to our Character's Player Controller     AController* CharacterController = Character->GetController();     RestartPlayer(CharacterController); }          

Implementing the RespawnPlayerCharacter

You will now be tasked with implementing the logic used to destroy the RespawnPlayerCharacter, and implement respawn through the RespawnPlayerGameMode's class.

  1. From the Content Browser, navigate to your C++ Classes folder and double-click the RespawnPlayerCharacter to open its RespawnPlayerCharacter.h file.

    image alt text

  2. Inside the RespawnPlayerCharacter.h file, declare the following code:

                    protected:      //Called when our Actor is destroyed during Gameplay.     virtual void Destroyed();      //Call Gamemode class to Restart Player Character.     void CallRestartPlayer();              

    In this declaration, the Destroyed method is marked with virtual because the Character class inherits from the Actor class, which contains its own destroyed method.

  3. Navigate to your RespawnPlayerCharacter.cpp file, then declare the following class library include:

                    #include "RespawnPlayerGameMode.h"              

    You will include the Gamemode library declaration to later call its class functionality from thePlayer Character class.

  4. Next, add the following RespawnPlayerCharacter class methods.

                    void ARespawnPlayerCharacter::Destroyed() {     Super::Destroyed();      // Example to bind to OnPlayerDied event in GameMode.      if (UWorld* World = GetWorld())     {         if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode()))         {             GameMode->GetOnPlayerDied().Broadcast(this);         }     } }  void ARespawnPlayerCharacter::CallRestartPlayer() {     //Get a reference to the Pawn Controller.     AController* CortollerRef = GetController();      //Destroy the Player.        Destroy()      //Get the World and GameMode in the world to invoke its restart player function.     if (UWorld* World = GetWorld())     {         if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode()))         {             GameMode->RestartPlayer(CortollerRef);         }     } }  void ARespawnPlayerCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) {     //Sets up an input key action to call Restart Player.     PlayerInputComponent->BindAction("Restart", IE_Pressed, this, &ARespawnPlayerCharacter::CallRestartPlayer); }              

    The `CallRestart`Player function will Destroy the player character and is called when the **R** key is pressed. The **Destroy **method will usually be called when the player loses enough health from a Gameplay event that causes your player character to despawn.

  5. Compile your code.

Finished Code

RespawnPlayerCharacter.h

            // Copyright Epic Games, Inc. All Rights Reserved.  #pragma once  #include "CoreMinimal.h" #include "GameFramework/Character.h" #include "RespawnPlayerCharacter.generated.h"  UCLASS(config=Game) class ARespawnPlayerCharacter : public ACharacter {     GENERATED_BODY()      /** Camera boom positioning the camera behind the character */     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))     class USpringArmComponent* CameraBoom;      /** Follow camera */     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))     class UCameraComponent* FollowCamera;  public:      ARespawnPlayerCharacter();      /** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)     float BaseTurnRate;      /** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)     float BaseLookUpRate;  protected:      virtual void BeginPlay();     virtual void Destroyed();     void CallRestartPlayer();      /** Resets HMD orientation in VR. */     void OnResetVR();      /** Called for forwards/backward input */     void MoveForward(float Value);      /** Called for side to side input */     void MoveRight(float Value);      /**       * Called via input to turn at a given rate.       * @param Rate  This is a normalized rate, i.e. 1.0 means 100% of desired turn rate      */     void TurnAtRate(float Rate);      /**      * Called via input to turn look up/down at a given rate.       * @param Rate  This is a normalized rate, i.e. 1.0 means 100% of desired turn rate      */     void LookUpAtRate(float Rate);      /** Handler for when a touch input begins. */     void TouchStarted(ETouchIndex::Type FingerIndex, FVector Location);      /** Handler for when a touch input stops. */     void TouchStopped(ETouchIndex::Type FingerIndex, FVector Location);  protected:      // APawn interface     virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;     // End of APawn interface  public:     /** Returns CameraBoom subobject **/     FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }      /** Returns FollowCamera subobject **/     FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; } };          

RespawnPlayer.cpp

            // Copyright Epic Games, Inc. All Rights Reserved.  #include "RespawnPlayerTestCharacter.h" #include "HeadMountedDisplayFunctionLibrary.h" #include "Camera/CameraComponent.h" #include "Components/CapsuleComponent.h" #include "Components/InputComponent.h" #include "GameFramework/CharacterMovementComponent.h" #include "GameFramework/Controller.h" #include "GameFramework/SpringArmComponent.h" #include "RespawnPlayerTestGameMode.h"  ////////////////////////////////////////////////////////////////////////// // ARespawnPlayerCharacter  ARespawnPlayerCharacter::ARespawnPlayerCharacter() {     // Set size for collision capsule     GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);      // set our turn rates for input     BaseTurnRate = 45.f;     BaseLookUpRate = 45.f;      // Don't rotate when the controller rotates. Let that just affect the camera.     bUseControllerRotationPitch = false;     bUseControllerRotationYaw = false;     bUseControllerRotationRoll = false;      // Configure character movement     GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...        GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f); // ...at this rotation rate     GetCharacterMovement()->JumpZVelocity = 600.f;     GetCharacterMovement()->AirControl = 0.2f;      // Create a camera boom (pulls in towards the player if there is a collision)     CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));     CameraBoom->SetupAttachment(RootComponent);     CameraBoom->TargetArmLength = 300.0f; // The camera follows at this distance behind the character        CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller      // Create a follow camera     FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));     FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation     FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm      // Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character)      // are set in the derived blueprint asset named MyCharacter (to avoid direct content references in C++)     static ConstructorHelpers::FObjectFinder<USkeletalMesh>SkeletalMeshAsset(TEXT("SkeletalMesh'/Game/Mannequin/Character/Mesh/SK_Mannequin.SK_Mannequin'"));     GetMesh()->SetSkeletalMesh(SkeletalMeshAsset.Object);     GetMesh()->SetRelativeLocation(FVector(0.0f, 0.0f, -97.0f));     GetMesh()->SetRelativeRotation(FQuat(FRotator(0.0f, 270.0f, 0.0f)));     static ConstructorHelpers::FObjectFinder<UAnimBlueprintGeneratedClass>AnimInstanceAsset(TEXT("AnimBlueprint'/Game/Mannequin/Animations/ThirdPerson_AnimBP.ThirdPerson_AnimBP_C'"));     GetMesh()->SetAnimInstanceClass(AnimInstanceAsset.Object); }  ////////////////////////////////////////////////////////////////////////// // Input  void ARespawnPlayerCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) {     // Set up gameplay key bindings     check(PlayerInputComponent);     PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);     PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);     PlayerInputComponent->BindAxis("MoveForward", this, &ARespawnPlayerCharacter::MoveForward);     PlayerInputComponent->BindAxis("MoveRight", this, &ARespawnPlayerCharacter::MoveRight);      // We have 2 versions of the rotation bindings to handle different kinds of devices differently     // "turn" handles devices that provide an absolute delta, such as a mouse.     // "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick     PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);     PlayerInputComponent->BindAxis("TurnRate", this, &ARespawnPlayerCharacter::TurnAtRate);     PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);     PlayerInputComponent->BindAxis("LookUpRate", this, &ARespawnPlayerCharacter::LookUpAtRate);      // handle touch devices     PlayerInputComponent->BindTouch(IE_Pressed, this, &ARespawnPlayerCharacter::TouchStarted);     PlayerInputComponent->BindTouch(IE_Released, this, &ARespawnPlayerCharacter::TouchStopped);      // VR headset functionality     PlayerInputComponent->BindAction("ResetVR", IE_Pressed, this, &ARespawnPlayerCharacter::OnResetVR);     PlayerInputComponent->BindAction("Restart", IE_Pressed, this, &ARespawnPlayerCharacter::CallRestartPlayer); }  void ARespawnPlayerCharacter::BeginPlay() {     Super::BeginPlay(); }  void ARespawnPlayerCharacter::Destroyed() {     Super::Destroyed();      // Example to bind to OnPlayerDied event in GameMode. This is _not_ a good idea if this game is multiplayer.     if (UWorld* World = GetWorld())     {         if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode()))         {             GameMode->GetOnPlayerDied().Broadcast(this);         }     } }  void ARespawnPlayerCharacter::CallRestartPlayer() {     AController* CortollerRef = GetController();     Destroy();      if (UWorld* World = GetWorld())     {         if (ARespawnPlayerGameMode* GameMode = Cast<ARespawnPlayerGameMode>(World->GetAuthGameMode()))         {             GameMode->RestartPlayer(CortollerRef);         }     } }  void ARespawnPlayerCharacter::OnResetVR() {     // If RespawnPlayer is added to a project via 'Add Feature' in the Unreal Editor the dependency on HeadMountedDisplay in RespawnPlayer.Build.cs is not automatically propagated     // and a linker error will result.     // You will need to either:     //      Add "HeadMountedDisplay" to [YourProject].Build.cs PublicDependencyModuleNames in order to build successfully (appropriate if supporting VR).     // or:     //      Comment or delete the call to ResetOrientationAndPosition below (appropriate if not supporting VR)     UHeadMountedDisplayFunctionLibrary::ResetOrientationAndPosition();     CallDestroyPlayer(); }  void ARespawnPlayerCharacter::TouchStarted(ETouchIndex::Type FingerIndex, FVector Location) {         Jump(); }  void ARespawnPlayerCharacter::TouchStopped(ETouchIndex::Type FingerIndex, FVector Location) {         StopJumping(); }  void ARespawnPlayerCharacter::TurnAtRate(float Rate) {     // calculate delta for this frame from the rate information     AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds()); }  void ARespawnPlayerCharacter::LookUpAtRate(float Rate) {     // calculate delta for this frame from the rate information     AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds()); }  void ARespawnPlayerCharacter::MoveForward(float Value) {     if ((Controller != nullptr) && (Value != 0.0f))     {         // find out which way is forward         const FRotator Rotation = Controller->GetControlRotation();         const FRotator YawRotation(0, Rotation.Yaw, 0);          // get forward vector         const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);         AddMovementInput(Direction, Value);     } }  void ARespawnPlayerCharacter::MoveRight(float Value) {     if ( (Controller != nullptr) && (Value != 0.0f) )     {         // find out which way is right         const FRotator Rotation = Controller->GetControlRotation();         const FRotator YawRotation(0, Rotation.Yaw, 0);          // get right vector          const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);         // add movement in that direction         AddMovementInput(Direction, Value);     } }          

End Result

Navigate back to the editor and click Play in Editor (PIE).

You can control your character's movement around the map by using the W, A, S, D keys.

When you press the R key your player character will be destroyed and will disappear momentarily before respawning at the Player Start Location.

image alt text

wenmislivend.blogspot.com

Source: https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/HowTo/RespawnPlayer

Post a Comment for "Need to Continue a Spawn After It is No Longer on the Screen Unreal Engine"