192 lines
5.1 KiB
C++
192 lines
5.1 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
#include "Grabber.h"
|
|
#include "DrawDebugHelpers.h"
|
|
#include "Engine/World.h"
|
|
#include "GameFramework/PlayerController.h"
|
|
#include "PhysicsEngine/PhysicsHandleComponent.h"
|
|
|
|
#define OUT //mark for outparameters (only for reading purposes)
|
|
// 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(); //Check for physics Handle Component
|
|
|
|
SetupInputComponent();
|
|
}
|
|
|
|
void UGrabber::FindPhysicsHandle()
|
|
{
|
|
PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>(); //<> for function templates
|
|
if(!PhysicsHandle) // same as if(PhysicsHandle == nullptr)
|
|
{
|
|
UE_LOG(LogTemp, Error, TEXT("No Physics handle component found on: %s !"), *GetOwner()->GetName());
|
|
}
|
|
}
|
|
|
|
void UGrabber::SetupInputComponent()
|
|
{
|
|
InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
|
|
if(InputComponent)
|
|
{
|
|
//UE_LOG(LogTemp, Warning, TEXT("Input Component found on: %s !"), *GetOwner()->GetName());
|
|
InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab); // User Input zu einem funktionsaufruf binden // Name der funktion beim keypress gleich name vom action in projectsettings , IE = InputEvent
|
|
InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::GrabRelease);
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogTemp, Error, TEXT("Input Component MISSING on: %s !"), *GetOwner()->GetName());
|
|
}
|
|
}
|
|
|
|
void UGrabber::Grab()
|
|
{
|
|
//only Raycast, when key is pressed and Try and reach any actor with physics body collision set.
|
|
FHitResult HitResult = GetFirstPhysicsBodyInReach();
|
|
UPrimitiveComponent* ComponentToGrab = HitResult.GetComponent();
|
|
AActor* ActorHit = HitResult.GetActor();
|
|
|
|
//if we hit something, attach physics handle
|
|
if(ActorHit) //if an actor is hit, then attach PhysicsHandle
|
|
{
|
|
if(!PhysicsHandle){return;}
|
|
PhysicsHandle->GrabComponentAtLocation
|
|
(
|
|
ComponentToGrab,
|
|
NAME_None,
|
|
GetLineTraceEnd()
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
void UGrabber::GrabRelease()
|
|
{
|
|
//Remove, release physicshandle
|
|
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 PhysicsBody attached
|
|
if(PhysicsHandle->GrabbedComponent)
|
|
{
|
|
//move object we are holding
|
|
PhysicsHandle->SetTargetLocation(GetLineTraceEnd());
|
|
}
|
|
|
|
// DrawDebugLine(
|
|
// GetWorld(),
|
|
// GetPlayerWorldPosition(),
|
|
// GetLineTraceEnd(),
|
|
// FColor(0, 255 , 0), //red, green, blue,
|
|
// false,
|
|
// 0.f,
|
|
// 0,
|
|
// 5.f
|
|
// );
|
|
}
|
|
|
|
FHitResult UGrabber::GetFirstPhysicsBodyInReach() const
|
|
{
|
|
FHitResult Hit;
|
|
//Raycast out to a certain distance (Reach)
|
|
FCollisionQueryParams TraceParams(FName(TEXT("")), false, GetOwner()); //fname, ComplexCollision=false, ignore hit on owner(origin point)
|
|
|
|
GetWorld()->LineTraceSingleByObjectType(
|
|
OUT Hit,
|
|
GetPlayerWorldPosition(), //PlayerViewPointLocation
|
|
GetLineTraceEnd(),
|
|
FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody), //:: to accsess an enum
|
|
TraceParams
|
|
);
|
|
return Hit;
|
|
}
|
|
|
|
FVector UGrabber::GetPlayerWorldPosition() const
|
|
{
|
|
//Get Player Viewport
|
|
FVector PlayerViewPointLocation;
|
|
FRotator PlayerViewPointRotation;
|
|
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(
|
|
OUT PlayerViewPointLocation,
|
|
OUT PlayerViewPointRotation
|
|
);
|
|
|
|
return PlayerViewPointLocation;
|
|
}
|
|
|
|
FVector UGrabber::GetLineTraceEnd() const //Players Reach
|
|
{
|
|
//Get Player Viewport
|
|
FVector PlayerViewPointLocation;
|
|
FRotator PlayerViewPointRotation;
|
|
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(
|
|
OUT PlayerViewPointLocation,
|
|
OUT PlayerViewPointRotation
|
|
);
|
|
|
|
return PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
|
|
}
|
|
|
|
//comments
|
|
//Logging out to test
|
|
// UE_LOG(LogTemp, Warning, TEXT("Location: %s, Rotation= %s"),
|
|
// *PlayerViewPointLocation.ToString(),
|
|
// *PlayerViewPointRotation.ToString()
|
|
// );
|
|
|
|
/*
|
|
//Get Player Viewport
|
|
FVector PlayerViewPointLocation;
|
|
FRotator PlayerViewPointRotation;
|
|
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(
|
|
OUT PlayerViewPointLocation,
|
|
OUT PlayerViewPointRotation
|
|
);
|
|
|
|
//GetPhysicsbodyInReach
|
|
//Draw a Line from the Player showing the Reach
|
|
FVector LineTraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
|
|
// DEBUG
|
|
// DrawDebugLine(
|
|
// GetWorld(),
|
|
// PlayerViewPointLocation,
|
|
// LineTraceEnd,
|
|
// FColor(0, 255 , 0) //red, green, blue,
|
|
// false,
|
|
// 0.f,
|
|
// 0,
|
|
// 5.f
|
|
// );
|
|
*/
|
|
|
|
//return name of hit actor
|
|
//See what it hits
|
|
// if(Hit.GetActor())
|
|
// UE_LOG(LogTemp, Warning, TEXT("Hit: %s"), *Hit.GetActor()->GetName());
|
|
//or
|
|
/*
|
|
AActor* ActorHit = Hit.GetActor();
|
|
|
|
//Log out to Test
|
|
if(Hit.GetActor())
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("Hit: %s"), *ActorHit->GetName());
|
|
}
|
|
*/ |