Here’s my version of the Grabber Component. I feel like it’s a lot shorter, and uses the LineTraceByChannel instead of Object! Also, it uses the GrabComponentAtLocationWithRotation() function, so that the object stops rotating non stop xD
#include "GrabberComponent.h"
#include "Components/PrimitiveComponent.h"
#include "Components/InputComponent.h"
#include "Engine/World.h"
// Sets default values for this component's properties
UGrabberComponent::UGrabberComponent()
{
// 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.
PrimaryComponentTick.bCanEverTick = true;
}
// Called when the game starts
void UGrabberComponent::BeginPlay()
{
Super::BeginPlay();
Actor = GetOwner();
InputComponent = Actor->FindComponentByClass<UInputComponent>();
PhysicsHandler = Actor->FindComponentByClass<UPhysicsHandleComponent>();
if(InputComponent)
{
SetupInput();
}
else
{
UE_LOG(LogTemp,Error,TEXT("Input Component is not working"));
}
if(PhysicsHandler) { UE_LOG(LogTemp,Warning,TEXT("Physics Handler is set up!"));}
else{ UE_LOG(LogTemp,Error,TEXT("Physics Handler is set up!")); }
}
// Called every frame
void UGrabberComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if(PhysicsHandler->GrabbedComponent)
{
FVector outLocation;
FRotator outRotation;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(outLocation, outRotation);
endLocation = outLocation + outRotation.Vector() * 200;
PhysicsHandler->SetTargetLocation(
endLocation
);
}
// ...
}
void UGrabberComponent::SetupInput()
{
InputComponent->BindAction("Grab",IE_Pressed,this,&UGrabberComponent::Grab);
InputComponent->BindAction("Grab",IE_Released,this,&UGrabberComponent::Release);
}
void UGrabberComponent::Grab()
{
UE_LOG(LogTemp,Warning,TEXT("Grabbing!!"));
Linetracing();
}
void UGrabberComponent::Release()
{
UE_LOG(LogTemp,Warning,TEXT("Releasing!!"));
PhysicsHandler->ReleaseComponent();
}
void UGrabberComponent::Linetracing()
{
FVector outLocation;
FRotator outRotation;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(outLocation, outRotation);
endLocation = outLocation + outRotation.Vector() * 200; //Reach can be changed later...
FHitResult hit;
FCollisionQueryParams params(FName(TEXT("")),false,GetOwner());
GetWorld()->LineTraceSingleByChannel(
hit,outLocation, endLocation, ECollisionChannel::ECC_PhysicsBody, params
);
if(hit.GetActor())
{
UE_LOG(LogTemp, Warning, TEXT("Hit object %s"),*hit.GetActor()->GetName());
UPrimitiveComponent* ComponentToGrab = hit.GetComponent();
PhysicsHandler->GrabComponentAtLocationWithRotation(
ComponentToGrab,
NAME_None,
endLocation,
FRotator(0.0f,0.0f,0.0f)
);
}
}