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.
ToonTanksGameMode.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "ToonTanksGameMode.generated.h"
UCLASS()
class TOONTANKS_API AToonTanksGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
virtual APawn* SpawnDefaultPawnAtTransform_Implementation(AController* NewPlayer, const FTransform& SpawnTransform) override;
};
ToonTanksGameMode.cpp
#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;
Params.AddIgnoredActor(SpawnedPawn);
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.