A generic solution for the floating tank problem

I’m taking advantage of the newly created ToonTanksGameMode class and doing a line trace down to find the ground when it spawns the pawn.


#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "ToonTanksGameMode.generated.h"

class TOONTANKS_API AToonTanksGameMode : public AGameModeBase

	virtual APawn* SpawnDefaultPawnAtTransform_Implementation(AController* NewPlayer, const FTransform& SpawnTransform) override;


#include "ToonTanksGameMode.h"

#include "Components/CapsuleComponent.h"

APawn* AToonTanksGameMode::SpawnDefaultPawnAtTransform_Implementation(AController* NewPlayer, const FTransform& SpawnTransform)
	APawn* SpawnedPawn = Super::SpawnDefaultPawnAtTransform_Implementation(NewPlayer, SpawnTransform);
	if (SpawnedPawn)
		if (const UCapsuleComponent* CapsuleComponent = Cast<UCapsuleComponent>(SpawnedPawn->GetRootComponent()))
			// Perform a line trace to find the ground and position the pawn
			FHitResult Hit;
			const FVector Start = SpawnedPawn->GetActorLocation();
			const FVector End = Start - FVector(0.f, 0.f, 1000.f);  // Check below the Player Start
			FCollisionQueryParams Params;
			GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_Visibility, Params);

			if (Hit.bBlockingHit)
				// Place the pawn on the hit location offsetting by the capsule half height with 0.1 margin to be safe 
				SpawnedPawn->SetActorLocation(Hit.Location + FVector(0, 0, CapsuleComponent->GetScaledCapsuleHalfHeight() + 0.1f));
	return SpawnedPawn;

It’s weird that we have this problem in the first place, though. I mean it’s natural to assume that people would want to use PlayerStart actor with smaller/bigger pawns than the standard one. So there must be an easier solution, I hope.

Privacy & Terms