Produktion_Digitaler_Medien/Source/BuildingEscape/Grabber.cpp

181 lines
4.9 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "DrawDebugHelpers.h"
#include "Engine/World.h"
#include "GameFramework/PlayerController.h"
#include "PhysicsEngine/PhysicsHandleComponent.h"
#include "Grabber.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());
}
}
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());
}
*/