Can't respawn player

Hello, so i’ve been trying to respawn player in multiplayer in c++.
After death body play animation and after 5 seconds player is respawned.
Im not doing anything in gamemode(is this the issue?)
The problem is: when i DetachFromControllerPendingDestroy the controller is null and i can’t respawn player, but when i execute my code without detaching player respawns correctly(Player can’t move while animation of death is playing).
Here is my code( Character.cpp):

#include "Scharacter.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/PawnMovementComponent.h"
#include "Sweapon.h"
#include "Components/CapsuleComponent.h"
#include "Extremegamev2.h"
#include "SHealthComponent.h"
#include "Net/UnrealNetwork.h"
#include "GameFramework/PlayerController.h"
#include "TimerManager.h"
#include "Engine/World.h"
#include "Kismet/GameplayStatics.h"
#include "Engine/Classes/GameFramework/GameModeBase.h"
#include "GameFramework/Actor.h"
#include "GameFramework/GameSession.h"
#include "SGameMode.h"


AScharacter::AScharacter()
{
 	
	PrimaryActorTick.bCanEverTick = true;

	SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComp"));
	SpringArmComp->bUsePawnControlRotation = true;
	SpringArmComp->SetupAttachment(RootComponent);
	

	GetMovementComponent()->GetNavAgentPropertiesRef().bCanCrouch = true;

	GetCapsuleComponent()->SetCollisionResponseToChannel(COLLISION_WEAPON, ECR_Ignore);

	HealthComp = CreateDefaultSubobject<USHealthComponent>(TEXT("HealthComp"));


	CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComp"));
	CameraComp->SetupAttachment(SpringArmComp);


	ZoomedFOV = 65.0f;
	ZoomInterpSpeed = 20;

	WeaponAttachSocketName = "WeaponSocket";
	
	
}

// Called when the game starts or when spawned
void AScharacter::BeginPlay()
{

	
	

	Super::BeginPlay();
	
	

	DefaultFOV = CameraComp->FieldOfView;
	HealthComp->OnHealthChanged.AddDynamic(this, &AScharacter::OnHealthChanged);

	if (Role == ROLE_Authority)
	{
		// Spawn a default weapon
		FActorSpawnParameters SpawnParams;
		SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;

		CurrentWeapon = GetWorld()->SpawnActor<ASweapon>(StarterWeaponClass, FVector::ZeroVector, FRotator::ZeroRotator, SpawnParams);
		if (CurrentWeapon)
		{
			CurrentWeapon->SetOwner(this);
			CurrentWeapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, WeaponAttachSocketName);
		}
	}
	


}

void AScharacter::MoveForward(float Value)
{
	AddMovementInput(GetActorForwardVector() , Value);
}

void AScharacter::MoveRight(float Value)
{
	AddMovementInput(GetActorRightVector(), Value);
}

void AScharacter::BeginCrouch()
{
	Crouch();
}

void AScharacter::EndCrouch()
{
	UnCrouch();
}

void AScharacter::BeginZoom()
{
	bWantsToZoom = true;
}

void AScharacter::EndZoom()
{
	bWantsToZoom = false;
}

void AScharacter::StartFire()
{

	if (CurrentWeapon) {
		CurrentWeapon->StartFire();
	}

}

void AScharacter::StopFire()
{
	if (CurrentWeapon) {
		CurrentWeapon->StopFire();
	}
}
void AScharacter::OnHealthChanged(USHealthComponent* HealthComp, float Health, float HealthDelta, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser)
{
	if (Health <= 0.0f && !bDied) {
		

		FTimerHandle TimerHandle;

		

		

		bDied = true;
		

		GetMovementComponent()->StopMovementImmediately();
		GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
		DetachFromControllerPendingDestroy();
		
		SetLifeSpan(5.0f);
	
		//CurrentWeapon->SetLifeSpan(5.0f);
		
		

	}

}


// Called every frame
void AScharacter::Tick(float DeltaTime)
{
	
	Super::Tick(DeltaTime);


	float TargetFOV = bWantsToZoom ? ZoomedFOV : DefaultFOV;

	float NewFOV = FMath::FInterpTo(CameraComp->FieldOfView, TargetFOV, DeltaTime, ZoomInterpSpeed);


	CameraComp->SetFieldOfView(NewFOV);

	

}

// Called to bind functionality to input
void AScharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	PlayerInputComponent->BindAxis("MoveForward", this, &AScharacter::MoveForward);
	PlayerInputComponent->BindAxis("MoveRight", this, &AScharacter::MoveRight);

	PlayerInputComponent->BindAxis("LookUp", this, &AScharacter::AddControllerPitchInput);
	PlayerInputComponent->BindAxis("Turn", this, &AScharacter::AddControllerYawInput);

	PlayerInputComponent->BindAction("Crouch",IE_Pressed, this, &AScharacter::BeginCrouch);
	PlayerInputComponent->BindAction("Crouch", IE_Released, this, &AScharacter::EndCrouch);

	PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AScharacter::Jump);

	PlayerInputComponent->BindAction("Zoom", IE_Pressed, this, &AScharacter::BeginZoom);
	PlayerInputComponent->BindAction("Zoom", IE_Released, this, &AScharacter::EndZoom);

	PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AScharacter::StartFire);
	PlayerInputComponent->BindAction("Fire", IE_Released, this, &AScharacter::StopFire);



}
FVector AScharacter::GetPawnViewLocation() const
{
	
	if (CameraComp)
	{
		return CameraComp->GetComponentLocation();
	}
	return Super::GetPawnViewLocation();
}


void AScharacter::LifeSpanExpired()
{    

	APlayerController* playerController = Cast<APlayerController>(GetController());
	
	Super::LifeSpanExpired();

	if (playerController)
	{
		playerController->ServerRestartPlayer();
	}
	
}

void AScharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	DOREPLIFETIME(AScharacter, bDied);
	DOREPLIFETIME(AScharacter, CurrentWeapon); 
	
}

void AMBaseCharacter::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
AMultiplayerGameModeBase *GM = Cast(GetWorld()->GetAuthGameMode());
if (GM)
{
GM->RespawnDeadPlayer();
}
}

You are absolutely right with thinking about the game mode side of things. I typically override EndPlay (considering that is one of the last functions to be called before destroying the actor). and respawn the player that way.

GAMEMODE

void AMultiplayerGameModeBase::RespawnDeadPlayer()
{
	for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
	{
		if (!(Iterator->IsValid())) continue;

		APlayerController *PC = Iterator->Get();
		if (PC && PC->GetPawn() == nullptr)
		{
			RestartPlayer(PC);
		}
	}
}

I love you CHADALAK :smiley: Now everything makes sense :slight_smile: