Possess on Linetrace Hit. From BP to C++

Hi

How would I go about adding this BP code into C++, more so the Interface message

What I’m looking for is to be able to call Possess() on another instance on the same class while passing in the Controller of the one who instigated the line trace

What I’ve got so far in my .cpp file

void ARayCastTestCharacter::PossessCharacter()
{
	AController* PossingController = this->GetController();

	FVector Start = FirstPersonCameraComponent->GetComponentLocation();
	FVector End = Start + FirstPersonCameraComponent->GetForwardVector() * PossessDist;

	FHitResult HitResult;
	FCollisionQueryParams Param;
	TArray <AActor*>ActorsToIgnore;

	bool HasHit = UKismetSystemLibrary::LineTraceSingle(GetWorld(), 
		Start, 
		End, 
		ETraceTypeQuery::TraceTypeQuery3, 
		false, 
		ActorsToIgnore, 
		EDrawDebugTrace::ForDuration,
		HitResult, 
		true);

	DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 5);
	DrawDebugSphere(GetWorld(), HitResult.ImpactPoint, 10, 10, FColor::Red, false, 5);

	if (HasHit)
	{
		PossessAI(PossingController);
		UE_LOG(LogTemp, Warning, TEXT("New Actor hit by trace %s"), *HitResult.GetActor()->GetActorNameOrLabel());
	}
}

void ARayCastTestCharacter::PossessAI(AController* PossessingController)
{
	if (PossessingController) { UE_LOG(LogTemp, Error, TEXT("(PossessingController) was nullptr")); return; }
	PossessingController->Possess(this);
}

The way to do it is to define the interface in C++, and then call it as a normal C++ method.

AController* PossingController = this->GetController();
...
if (HasHit)
    PossessAI(PossingController);
...
PossessingController->Possess(this);

You are possessing yourself after any successful trace, that doesn’t make sense.
It would make more sense to check the hit result actor, and possess it if it is a pawn. Something like :

auto HitPawn = Cast<APawn>(HitResult.GetActor());
if (HitPawn)
    PossingController->Possess(HitPawn);

If you want to use an interface it’s very similar but your have to use c++ specifics for interfaces. Something like :

auto IPossess = Cast<IPossessInterface(HitResult.GetActor());
if (IPossess)
    IPossessInterface::Execute_PossessAI(IPossess, PossingController);

This of course requires you implement the interface in C++.


If this is too much of a burden you can call the blueprint interface but that’s probably not recommended :

if (APawn* P = Cast<APawn>(HitResult.GetActor()))
{
    if (UFunction* Func = P->FindFunction("PossessAI"))
    {
        struct temp { UObject* a; APlayerController* b; } Parms = { HitResult.GetActor(), PossessController };
        P->ProcessEvent(Func, &Parms);
    }
}
1 Like

Thanks alot :slight_smile: