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.
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.
-
Begin by creating a new Games > Third Person > Blueprint project named RespawnPlayer.
-
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.
-
Set the Restart Action Mapping key value to R.
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.
-
From the Content Browser navigate to Content > ThirdPersonBP and double-click the ThirdPersonGameMode Blueprint to open its Class Defaults.
-
In the Class Defaults , click the Open Full Blueprint Editor link.
-
From the My Blueprint panel, navigate to the Event Dispatchers category and click the Add (+) button to create a new Event Dispatcher named OnPlayerDied.
-
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.
-
Right-click the Event Graph to bring up the Actions menu, then search for and select Event BeginPlay.
-
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.
-
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.
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.
-
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.
-
From the PlayerDied node, drag from the execution pin, then from the Actions menu, search for and select the Restart Player function.
-
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.
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.
-
Click Compile and Save.
Finished Blueprint
Implementing the RespawnPlayerCharacter Class
You will now be implementing the logic to destroy the RespawnPlayerCharacter and call the GameMode's RestartPlayer method.
-
From the Content Browser navigate to Content > ThirdPersonBP and double-click the ThirdPersonCharacter to open its Class Defaults.
-
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.
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.
-
Drag from the Event Destroyed execution pin and from the Actions menu, search for and select Cast to Third Person Game Mode.
-
From the Cast to Third Person Game Mode node, drag from the Object pin, then search for and select the Get Game Mode node.
-
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.
-
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.
-
From the My Blueprint tab, navigate to the Functions category and click the Add (+) button to create a new function named Call Restart Player.
-
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.
-
Drag the ControllerRef variable onto the Execution pin of the Call Restart Player node.
-
Drag from the ControllerRef pin, and from the Actions menu, search for and select Get Controller from the Pawn category.
-
Navigate back to the Set ControllerRef node, then drag from the execution pin and from the Actions menu search for and select DestroyActor.
-
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.
-
From the Cast to Third Person Game Mode node, drag from the Object pin, then search for and select the Get Game Mode node.
-
From the Third Person Game Mode node, drag from the As Third Person Game mode pin, then search for and select for RestartPlayer.
-
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.
-
Click Compile and Save.
Your completed Call Restart Player function will appear as it does below.
-
Navigate back to the Event Graph, then right-click, search for, and select the Restart Input Action Event.
-
Drag off of the Pressed key pin, then from the Actions menu, search for and select Call Restart Player.
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.
-
Click Compile and Save
Finished Blueprint
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.
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.
-
Begin by creating a new Games > Third Person > C++ project named RespawnPlayer.
-
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.
-
Set the Restart Action Mapping key value to R.
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.
-
From the Content Browser, navigate to your C++ Classes folder and double-click the RespawnPlayerGameMode to open its
RespawnPlayerGameMode.h
. -
Inside the
RespawnPlayerGameMode.h
file, declare the following code under your library include declarationsDECLARE_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.
-
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.
-
Navigate to your
RespawnPlayerGameMode.cpp
file and implement the following class methodsvoid 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); }
-
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.
-
From the Content Browser, navigate to your C++ Classes folder and double-click the RespawnPlayerCharacter to open its
RespawnPlayerCharacter.h
file.
-
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. -
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.
-
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.
-
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.
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"