#pragma region 

// #define OUT
// 
// #pragma region 
// 
// #include "Grabber.h"
// #include "DrawDebugHelpers.h"
// #include "Engine/World.h"
// #include "GameFramework/PlayerController.h"
// #include "CollisionQueryParams.h"
// 
// #pragma endregion Including Header Files
// 
// #pragma region 
// 
// 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;
// 
// 
// }
// 
// #pragma endregion Constructor
// 
// #pragma region 
// 
// void UGrabber::BeginPlay()
// {
// 	Super::BeginPlay();
// 
// 	FindPhysicsHandle();
// 	SetupInputComponent();
// }
// 
// #pragma endregion Begin Play
// 
// #pragma region
// 
// void UGrabber::SetupInputComponent()
// {
// 	InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
// 	if (InputComponent != nullptr)
// 	{
// 		UE_LOG(LogTemp, Warning, TEXT("Input Component found on the actor"));
// 		InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab);
// 		InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::Release);
// 	}
// }
// 
// void UGrabber::FindPhysicsHandle()
// {
// 	PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
// 	if (PhysicsHandle != nullptr)
// 	{
// 		UE_LOG(LogTemp, Warning, TEXT("Physics handle found !!!00"));
// 	}
// 	else
// 	{
// 		UE_LOG(LogTemp, Error, TEXT("PhysicsHandle is null..."));
// 	}
// }
// 
// #pragma endregion Initialize Components
// 
// #pragma region 
// 
// void UGrabber::Release()
// {
// 	UE_LOG(LogTemp, Warning, TEXT("Grabbed Object Released"));
// 
// 	PhysicsHandle->ReleaseComponent();
// }
// 
// void UGrabber::Grab()
// {
// 	UE_LOG(LogTemp, Warning, TEXT("Grab"));
// 
// 	FHitResult HitResult = GetFirstPhysicsBodyInReach();
// 	UPrimitiveComponent* ComponentToGrab = HitResult.GetComponent();
// 
// 	if (HitResult.GetActor() != nullptr)
// 	{
// 		PhysicsHandle->GrabComponentAtLocation
// 		(
// 			ComponentToGrab,
// 			NAME_None,
// 			GetLineTraceEnd()
// 		);
// 	}
// 
// }
// 
// #pragma endregion Input Callbacks
// 
// #pragma region
// 
// void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
// {
// 	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// 
// 	if (PhysicsHandle->GrabbedComponent)
// 	{
// 		PhysicsHandle->SetTargetLocation(GetLineTraceEnd());
// 	}
// }
// 
// 
// #pragma endregion Tick Component
// 
// #pragma region
// 
// FVector UGrabber::GetLineTraceEnd() 
// {
// 
// 	 PlayerViewPointLocation;
// 	 PlayerViewPointRotation;
// 
// 	GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(
// 		OUT PlayerViewPointLocation,
// 		OUT PlayerViewPointRotation
// 	);
// 
// 	LineTraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
// 
// 	return LineTraceEnd;
// }
//  
// FHitResult UGrabber::GetFirstPhysicsBodyInReach() 
// {
// 	FHitResult Hit;
// 	FCollisionQueryParams TraceParams(FName(TEXT("")), false, GetOwner());
// 
// 	FVector EndOfLineTrace = GetLineTraceEnd();
// 
// 	GetWorld()->LineTraceSingleByObjectType
// 	(
// 		OUT Hit,
// 		PlayerViewPointLocation,
// 		EndOfLineTrace,
// 		FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
// 		TraceParams
// 	);
// 
// 	if (Hit.GetActor() != nullptr)
// 		UE_LOG(LogTemp, Warning, TEXT("%s : %f"), *Hit.GetActor()->GetName(), GetWorld()->GetTimeSeconds());
// 
// 	return Hit;
// 
// }
// #pragma endregion Getters

#pragma endregion MyCode 







#pragma region

#define OUT

#pragma region 

#include "Grabber.h"
#include "DrawDebugHelpers.h"
#include "Engine/World.h"
#include "GameFramework/PlayerController.h"
#include "CollisionQueryParams.h"

#pragma endregion Including Header Files

#pragma region 

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;


}

#pragma endregion Constructor

#pragma region 

void UGrabber::BeginPlay()
{
	Super::BeginPlay();

	FindPhysicsHandle();
	SetupInputComponent();
}

#pragma endregion Begin Play

#pragma region

void UGrabber::SetupInputComponent()
{
	InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
	if (InputComponent != nullptr)
	{
		UE_LOG(LogTemp, Warning, TEXT("Input Component found on the actor"));
		InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab);
		InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::Release);
	}
}

void UGrabber::FindPhysicsHandle()
{
	PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
	if (PhysicsHandle != nullptr)
	{
		UE_LOG(LogTemp, Warning, TEXT("Physics handle found !!!00"));
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("PhysicsHandle is null..."));
	}
}

#pragma endregion Initialize Components

#pragma region 

void UGrabber::Release()
{
	UE_LOG(LogTemp, Warning, TEXT("Grabbed Object Released"));

	PhysicsHandle->ReleaseComponent();
}

void UGrabber::Grab()
{
	UE_LOG(LogTemp, Warning, TEXT("Grab"));

	FHitResult HitResult = GetFirstPhysicsBodyInReach();
	UPrimitiveComponent* ComponentToGrab = HitResult.GetComponent();

	if (HitResult.GetActor() != nullptr)
	{
		PhysicsHandle->GrabComponentAtLocation
		(
			ComponentToGrab,
			NAME_None,
			GetPlayerReach()
		);
	}

}

#pragma endregion Input Callbacks

#pragma region

void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

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

#pragma endregion Tick Component

#pragma region

FHitResult UGrabber::GetFirstPhysicsBodyInReach() const
{
	FHitResult Hit;
	FCollisionQueryParams TraceParams(FName(TEXT("")), false, GetOwner());

	FVector EndOfLineTrace = GetPlayerReach();

	GetWorld()->LineTraceSingleByObjectType
	(
		OUT Hit,
		GetPlayerWorldPosition(),
		EndOfLineTrace,
		FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
		TraceParams
	);

	return Hit;
}

FVector UGrabber::GetPlayerReach() const
{
	FVector PlayerViewPointLocation;
	FRotator PlayerViewPointRotation;

	GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint
	(
		OUT PlayerViewPointLocation,
		OUT PlayerViewPointRotation
	);

	return PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
}

FVector UGrabber::GetPlayerWorldPosition() const
{
	FVector PlayerViewPointLocation;
	FRotator PlayerViewPointRotation;

	GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint
	(
		OUT PlayerViewPointLocation,
		OUT PlayerViewPointRotation
	);

	return PlayerViewPointLocation;
}

#pragma endregion Getters

#pragma endregion GameDev.Tv's Code