Finally, I’m on refactoring rules. Why not declare variables in the header file so the variables can be accessed anywhere inside the class instead of creating a new function? Is it gonna affect the performance? I think it’s simpler this way.
This is my .cpp file.
#include "Grabber.h"
#include "Engine/World.h"
#include "GameFramework/PlayerController.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.
PrimaryComponentTick.bCanEverTick = true;
}
// Called when the game starts
void UGrabber::BeginPlay()
{
Super::BeginPlay();
FindPhysicsHandle();
SetupInput();
}
//Finding the physic handle
void UGrabber::FindPhysicsHandle() {
PhysicHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
if (PhysicHandle == nullptr) {
UE_LOG(LogTemp, Error, TEXT("PhysicalHandle doesn't assign to anything in actor : %s"), *GetOwner()->GetName())
}
}
//Setting up behavior when key is pressed
void UGrabber::SetupInput() {
InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
if (InputComponent) {
InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab);
InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::Release);
}
}
//Call out when key is pressed
void UGrabber::Grab() {
FHitResult HitResult = GetPlayerViewPointInReach();
UPrimitiveComponent* FocusedComponent = HitResult.GetComponent();
if (HitResult.GetActor()) {
PhysicHandle->GrabComponentAtLocation(FocusedComponent, NAME_None, LineTraceEnd);
}
}
//Call out when key is released
void UGrabber::Release() {
PhysicHandle->ReleaseComponent();
}
// Called every frame
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
//Set where the component will stay when grabbed
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(PlayerViewPointVector, PlayerViewPointRotator);
LineTraceEnd = PlayerViewPointVector + PlayerViewPointRotator.Vector() * Reach;
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (PhysicHandle->GrabbedComponent) {
PhysicHandle->SetTargetLocation(LineTraceEnd);
}
}
// Log out what trace hit
FHitResult UGrabber::GetPlayerViewPointInReach() const{
FHitResult Hit;
FCollisionQueryParams TraceParams(TEXT(""), false, GetOwner());
GetWorld()->LineTraceSingleByObjectType(Hit, PlayerViewPointVector, LineTraceEnd, ECC_PhysicsBody, TraceParams);
AActor* HitActor = Hit.GetActor();
if (HitActor) {
UE_LOG(LogTemp, Warning, TEXT("Trace Hit : %s"), *HitActor->GetName());
}
return Hit;
}