Is the code the problem? If not, What could it be.
Here is my code:
// Fill out your copyright notice in the Description page of Project Settings.
.CPP
#include "Grabber.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.h"
#include "Components/ActorComponent.h"
#include "PhysicsEngine/PhysicsHandleComponent.h"
#include "Engine/World.h"
#include "Engine/TriggerVolume.h"
#include "Engine/TriggerBox.h"
#include "PickUpComponent.h"
#include "Components/PrimitiveComponent.h"
#define Out // a macro named out
// 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;
// Set the SphereComponent as the root component.
//Create the static mesh component
}
// Called when the game starts
void UGrabber::BeginPlay()
{
Super::BeginPlay();
UE_LOG(LogTemp, Warning, TEXT("Grabber Reporting for Duty")); // activates if grabber works
//input
// input fuction
UGrabber::SetupInputComponent();
// Start with physics simulation disabled, for easy manipulation on UE4 Editor.
UGrabber::FindPhysicsHandleComponent();
UGrabber::FindPhysicsHandleComponent();
UGrabber::GetFirstPhysicsBodyReach();
// Attach the StaticMeshComponent to the RootComponent.
}
// Called every frame
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
FHitResult Hit;
FCollisionQueryParams TraceParameters(FName(TEXT("")), false, GetOwner());
FVector PlayerViewPointLocation;
FRotator PlayerViewPointRotation;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(PlayerViewPointLocation, PlayerViewPointRotation);
FVector LineTraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
Pawn = GetOwner();
GetWorld()->LineTraceSingleByObjectType(OUT Hit, PlayerViewPointLocation, LineTraceEnd, FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody), TraceParameters);
DrawDebugLine(GetWorld(), PlayerViewPointLocation, LineTraceEnd, FColor(255, 0, 0), false, 0.0f, 0.0f, 10.0f);
if (PhysicsHandle->GrabbedComponent)
{
UE_LOG(LogTemp, Warning, TEXT("Sucsess you are not an idiot"));
PhysicsHandle->SetTargetLocation(LineTraceEnd);
}
}
// input attached component
void UGrabber::SetupInputComponent()
{
InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
if (InputComponent)
{
InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::GrabP); // if Grab is Pressed
InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::GrabR); // if Grab is Released
}
else
{
UE_LOG(LogTemp, Error, TEXT("%s Missing Input Component"), *GetOwner()->GetName());
}
}
// gets physics component
void UGrabber::FindPhysicsHandleComponent()
{
PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
if (PhysicsHandle)
{
UE_LOG(LogTemp, Warning, TEXT("Sucsess you are not an idiot"));
}
else
{
UE_LOG(LogTemp, Error, TEXT("%s Missing Physics Handle Component"), *GetOwner()->GetName());
}
}
// grab whats in reach if pressed
void UGrabber::GrabP()
{
UE_LOG(LogTemp, Warning, TEXT("Grab Pressed"));
//auto vars
auto Hit = GetFirstPhysicsBodyReach();
auto ComponentToGrab = Hit.GetComponent();
auto ActorHit = Hit.GetActor();
if (ActorHit)
{
UE_LOG(LogTemp, Warning, TEXT("%s working"), *(GetOwner()->GetName()));
PhysicsHandle->GrabComponentAtLocationWithRotation(ComponentToGrab, NAME_None, ComponentToGrab->GetOwner()->GetActorLocation(), ComponentToGrab->GetOwner()->GetActorRotation());
}
}
//let go what is held if released
void UGrabber::GrabR()
{
UE_LOG(LogTemp, Warning, TEXT("Grab Released"));
}
const FHitResult UGrabber::GetFirstPhysicsBodyReach()
{
FHitResult Hit;
FCollisionQueryParams TraceParameters(FName(TEXT("")), false, GetOwner());
FVector PlayerViewPointLocation;
FRotator PlayerViewPointRotation;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(PlayerViewPointLocation, PlayerViewPointRotation);
Pawn = GetOwner();
FVector LineTraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
GetWorld()->LineTraceSingleByObjectType(OUT Hit, PlayerViewPointLocation, LineTraceEnd, FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody), TraceParameters);
DrawDebugLine(GetWorld(), PlayerViewPointLocation, LineTraceEnd, FColor(255, 0, 0), false, 0.0f, 0.0f, 10.0f);
FHitResult HitResult;
return FHitResult();
}
.H file
#include "PhysicsEngine/PhysicsHandleComponent.h"
#include "Engine/TriggerVolume.h"
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Grabber.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT13_API UGrabber : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UGrabber();
protected:
// Called when the game starts
virtual void BeginPlay() override;
void FindPhysicsHandleComponent();
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
private:
// how far ahead player can reach
float Reach = 100.f;
// input
void SetupInputComponent();
// Grab what is in reach or let go
void GrabP();
void GrabR();
UPhysicsHandleComponent* PhysicsHandle = nullptr;
UInputComponent* InputComponent = nullptr;
AActor* Pawn;
const FHitResult GetFirstPhysicsBodyReach();
};
I did some more experimenting I think the error has something to do with auto “ActorHit = Hit.GetActor().”
Hey there @Aidan_HK.
It’s been a while since I’ve done this particular module, but I’ll try to help out in anyway that I can. First things first, I’ve attached my (very) old working .cpp file to the bottom of this. It was created in 4.13, so it might not work depending on which engine version you are using, but being able to compare the logic should at least be helpful.
If it is not an issue within the .cpp file. The next place I would look is in your project settings to make sure that that you have an input event called “Grab”. After that, try to have the line trace log out any actors it hits. You can pass this into a UE_LOG using the *Hit.GetActor().GetName() function. If it is not hitting the chair, make sure that the chair has collision enabled.
Barring all of that, feel free to zip up the entire project, and I’ll take a look at it. I’m a much better debugger when I can see the whole picture.
#include "BuildingEscape.h"
#include "Grabber.h"
#define OUT
// 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.
bWantsBeginPlay = true;
PrimaryComponentTick.bCanEverTick = true;
}
// Called when the game starts
void UGrabber::BeginPlay()
{
Super::BeginPlay();
FindPhysicsHandleComponent();
SetupInputComponent();
}
// Called every frame
void UGrabber::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction )
{
Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
if (PhysicsHandle->GrabbedComponent)
{
if (!PhysicsHandle) { return; }
PhysicsHandle->SetTargetLocation(FindReachLineEnd());
}
}
void UGrabber::Grab()
{
UE_LOG(LogTemp, Warning, TEXT("Grab key pressed."));
///Try and find with physics body collision channel set
auto HitResult = GetFirstPhysicsBodyInReach();
auto ComponentToGrab = HitResult.GetComponent();
auto ActorHit = HitResult.GetActor();
if (ActorHit)
{
if (!PhysicsHandle) { return; }
PhysicsHandle->GrabComponent(
ComponentToGrab,
NAME_None,
ComponentToGrab->GetOwner()->GetActorLocation(),
true
);
}
}
void UGrabber::Release()
{
UE_LOG(LogTemp, Warning, TEXT("Grab key released."));
if (!PhysicsHandle) { return; }
PhysicsHandle->ReleaseComponent();
}
void UGrabber::FindPhysicsHandleComponent()
{
PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
if (PhysicsHandle == nullptr)
{
UE_LOG(LogTemp, Error, TEXT("Physics handle not found on %s"), *GetOwner()->GetName());
}
}
void UGrabber::SetupInputComponent()
{
InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
if (InputComponent)
{
InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab);
InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::Release);
}
else
{
UE_LOG(LogTemp, Error, TEXT("No input component found on %s"), *GetOwner()->GetName());
}
}
const FHitResult UGrabber::GetFirstPhysicsBodyInReach()
{
///Setup query parameters
FCollisionQueryParams TraceParameters(FName(TEXT("")), false, GetOwner());
/// Ray-cast out to reach distance
FHitResult HitResult;
GetWorld()->LineTraceSingleByObjectType(
OUT HitResult, //Out Parameter
FindReachLineStart(), //Line start location
FindReachLineEnd(), //Line End
FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody), //Type of object to check
TraceParameters //Parameters
);
// See what we hit
AActor* ActorHit = HitResult.GetActor();
return HitResult;
}
FVector UGrabber::FindReachLineStart()
{
FVector PlayerViewPointLocation;
FRotator PlayerViewPointRotation;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(
OUT PlayerViewPointLocation,
OUT PlayerViewPointRotation
);
return PlayerViewPointLocation;
}
FVector UGrabber::FindReachLineEnd()
{
FVector PlayerViewPointLocation;
FRotator PlayerViewPointRotation;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(
OUT PlayerViewPointLocation,
OUT PlayerViewPointRotation
);
FVector LineTraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
return LineTraceEnd;
}
I figured out the problem thanks to your help. The problem was "Simulate Physics" was not on, and "collision Presets" was not set to "PhysicsActor". I did a few edits to the code that Im not sure if they had any affect. Anyway thanks for the help and happy holidays.
Here is the Updated Program
.CPP
#include “Grabber.h”
#include “Engine/World.h”
#include “Engine/EngineTypes.h”
#include “DrawDebugHelpers.h”
#include “Components/ActorComponent.h”
#include “PhysicsEngine/PhysicsHandleComponent.h”
#include “Engine/World.h”
#include “Components/PrimitiveComponent.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();
UE_LOG(LogTemp, Warning, TEXT("Grabber Reporting for Duty")); // activates if grabber works
//input
// input fuction
// Start with physics simulation disabled, for easy manipulation on UE4 Editor.
UGrabber::FindPhysicsHandleComponent();
UGrabber::SetupInputComponent();
}
// Called every frame
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
FHitResult Hit;
FVector PlayerViewPointLocation;
FRotator PlayerViewPointRotation;
// set values
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(PlayerViewPointLocation, PlayerViewPointRotation);
FVector LineTraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
if (PhysicsHandle->GrabbedComponent)
{
UE_LOG(LogTemp, Warning, TEXT("Sucsess you are not an idiot good"));
PhysicsHandle->SetTargetLocation(LineTraceEnd);
}
}
void UGrabber::FindPhysicsHandleComponent()
{
PhysicsHandle = GetOwner()->FindComponentByClass();
if (PhysicsHandle)
{
UE_LOG(LogTemp, Warning, TEXT(“Sucsess 1”));
}
else
{
UE_LOG(LogTemp, Error, TEXT("%s Missing Physics Handle Component"), *(GetOwner()->GetName()));
}
}
void UGrabber::SetupInputComponent()
{
InputComponent = GetOwner()->FindComponentByClass();
if (InputComponent)
{
InputComponent->BindAction(“Grab”, IE_Pressed, this, &UGrabber::GrabP); // if Grab is Pressed
InputComponent->BindAction(“Grab”, IE_Released, this, &UGrabber::GrabR); // if Grab is Released
}
else
{
UE_LOG(LogTemp, Error, TEXT("%s Missing Input Component"), *(GetOwner()->GetName()));
}
}
void UGrabber::GrabP()
{
UE_LOG(LogTemp, Warning, TEXT(“Grab Pressed”));
//auto vars
auto Hit = GetFirstPhysicsBodyReach();
auto ComponentToGrab = Hit.GetComponent();
auto ActorHit = Hit.GetActor();
//error is here
if (ActorHit)
{
UE_LOG(LogTemp, Warning, TEXT("%s working"), *(GetOwner()->GetName()));
PhysicsHandle->GrabComponentAtLocation(ComponentToGrab, NAME_None, ComponentToGrab->GetOwner()->GetActorLocation());
}
else
{
UE_LOG(LogTemp, Warning, TEXT(“not working”));
}
}
void UGrabber::GrabR()
{
UE_LOG(LogTemp, Warning, TEXT(“Grab Released”));
}
const FHitResult UGrabber::GetFirstPhysicsBodyReach()
{
// vars
FHitResult Hit;
FCollisionQueryParams TraceParameters(FName(TEXT("")), false, GetOwner());
FVector PlayerViewPointLocation;
FRotator PlayerViewPointRotation;
// set values
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(PlayerViewPointLocation, PlayerViewPointRotation);
FVector LineTraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
GetWorld()->LineTraceSingleByObjectType(OUT Hit, PlayerViewPointLocation, LineTraceEnd, FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody), TraceParameters);
DrawDebugLine(GetWorld(), PlayerViewPointLocation, LineTraceEnd, FColor(255, 0, 0), false, 0.0f, 0.0f, 10.0f);
return Hit;
}
.H file
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include “Components/InputComponent.h”
#include “PhysicsEngine/PhysicsHandleComponent.h”
#include “CoreMinimal.h”
#include “Components/ActorComponent.h”
#include “Grabber.generated.h”
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class OFFICIAL_GAME_API UGrabber : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component’s properties
UGrabber();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
void FindPhysicsHandleComponent();
private:
// how far ahead player can reach
float Reach = 100.0f;
// input
void SetupInputComponent();
// Grab what is in reach or let go
void GrabP();
void GrabR();
UPhysicsHandleComponent* PhysicsHandle = nullptr;
UInputComponent* InputComponent = nullptr;
AActor* Pawn;
const FHitResult GetFirstPhysicsBodyReach();
};
This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.