Download

Grabber C++ componant not working on custom char

Hey all,

I have been having issues with my grabber componant I made in C++ I’m building a building escape game and with the defult pawn I can use the componant to pick up phisics objects but when I add the grabber and phisics handle to the custom char (From selection system) the phisics objects just bounce off my char and I cannot pick them up heres my grabber.cpp


// Fill out your copyright notice in the Description page of Project Settings.

#include "Building_Escape.h"
#include "Grabber.h"


// Sets default values for this component's properties
UGrabber::UGrabber()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	bWantsBeginPlay = true;
	PrimaryComponentTick.bCanEverTick = true;
}


// Called when the game starts
void UGrabber::BeginPlay()
{
	Super::BeginPlay();

	PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
	InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
	Handle();
	Component();
	
}

void UGrabber::Handle()
{
	if (PhysicsHandle == nullptr)

	{
		UE_LOG(LogTemp, Error, TEXT("%s Physics handle not found you may not pass"), *GetOwner()->GetName())
	}
}

void UGrabber::Component()
{
	if (InputComponent)
	{
			InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab);
		InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::Relise);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("%s Input Component not found you may not pass"), *GetOwner()->GetName())
	}
}

void UGrabber::Grab()
{
	
	UE_LOG(LogTemp, Warning, TEXT("Grab pressed!"))
	auto HitResult = GetFirstPhysicsBodyInReach();
	auto ComponentToGrab = HitResult.GetComponent();
	auto ActorHit = HitResult.GetActor();

	if (ActorHit)
	{
		if (!PhysicsHandle)
		{
			return;
		}
		PhysicsHandle->GrabComponent(
			ComponentToGrab,
			NAME_None,// No bones
			ComponentToGrab->GetOwner()->GetActorLocation(),
			true);// Allows rotation
	}
}
void UGrabber::Relise()
{
	if (!PhysicsHandle)
	{
		return;
	}
		PhysicsHandle->ReleaseComponent();
}
// Called every frame
void UGrabber::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction )
{
	Super::TickComponent( DeltaTime, TickType, ThisTickFunction );

	if(!PhysicsHandle)
	{
		return;

	}
	if (PhysicsHandle->GrabbedComponent)
	{
		PhysicsHandle->SetTargetLocation(GetReachLineEnd());
	}

	// ...
}

const FHitResult UGrabber::GetFirstPhysicsBodyInReach()
{


		FVector PlayerViewPointLocation;
		FRotator PlayerViewPointRotation;
		GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(
			OUT PlayerViewPointLocation,
			OUT PlayerViewPointRotation);
		FCollisionQueryParams TraceParameters(FName(TEXT("")), false, GetOwner());
		//Ray-Cast to reach distance
		FHitResult Hit;
		GetWorld()->LineTraceSingleByObjectType(
			OUT Hit,
			GetReachLineStart(),
			GetReachLineEnd(),
			FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
			TraceParameters
			);

		AActor* ActorHit = Hit.GetActor();
		if (ActorHit)
		{
			UE_LOG(LogTemp, Warning, TEXT("LineTraceHit %s"), *(ActorHit->GetName()))
		}
	
		return Hit;
}
FVector UGrabber::GetReachLineStart()
{
	FVector PlayerViewPointLocation;
	FRotator PlayerViewPointRotation;
	GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(
		OUT PlayerViewPointLocation,
		OUT PlayerViewPointRotation);
	return PlayerViewPointLocation;
}
FVector UGrabber::GetReachLineEnd()
{
	FVector PlayerViewPointLocation;
	FRotator PlayerViewPointRotation;
	GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(
		OUT PlayerViewPointLocation,
		OUT PlayerViewPointRotation);
	return PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
}

Grabber.h


public:	
	// Sets default values for this component's properties
	UGrabber();
	void Handle();
	void Component();
	// Called when the game starts
	virtual void BeginPlay() override;
	void Grab();
	void Relise();
	// Called every frame
	virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;
private:
	float Reach = 100.f;
	UPhysicsHandleComponent* PhysicsHandle = nullptr;
	UInputComponent* InputComponent = nullptr;
	const FHitResult GetFirstPhysicsBodyInReach();
	FVector GetReachLineStart();
	FVector GetReachLineEnd();
};

Hi and welcome to the forums.

I can’t spot anything obviously wrong right now, except maybe the GrabLocation parameter in the PhysicsHandle->GrabComponent could be HitResult.ImpactPoint instead.
Other than that may I suggest that you debug your Grabber component or at least add some more logging to see whether the different functions are called and behave as expected, especially those bound to the InputComponent?