I am new to coding in Unreal and i am still getting a hang of it. I am using Unreal Engine 4.22.3 and I am following a tutorial about coding in Unreal and i have came across this error where using Physics Handle crashes my unreal editor. The error log says that the engine crashed due to unhandled exception. It also reports that it happened as soon as line 81 in the code (see line 60 below in Grabber.cpp) was reached. When i checked line 81, it was pretty clear it was Physics handle causing the issue. i.e. this part of code is causing the issue:
// Attach a physics handle
PhysicsHandle->GrabComponentAtLocationWithRotation(
ComponentToGrab,
NAME_None,
ActorHit->GetOwner()->GetActorLocation(),
ActorHit->GetOwner()->GetActorRotation() // Allow rotation
);
i have confirmed this by commenting it out in my code and running and everything was working fine but i can't interact with anything(i.e i can't pickup object which is pretty obvious why). I am not sure what i am doing wrong as i am new to all this stuff and there isn't much about the error out there(I've bee looking for this since last 2 days on internet and nothing helped). I have really high hope with this forum and any help is greatly appreciated. I am attaching both the header and the actual implementation here to help understand the problem better.
//Grabber.h
// Attach a physics handle
PhysicsHandle->GrabComponentAtLocationWithRotation(
ComponentToGrab,
NAME_None,
ActorHit->GetOwner()->GetActorLocation(),
ActorHit->GetOwner()->GetActorRotation() // Allow rotation
);
i have confirmed this by commenting it out in my code and running and everything was working fine but i can't interact with anything(i.e i can't pickup object which is pretty obvious why). I am not sure what i am doing wrong as i am new to all this stuff and there isn't much about the error out there(I've bee looking for this since last 2 days on internet and nothing helped). I have really high hope with this forum and any help is greatly appreciated. I am attaching both the header and the actual implementation here to help understand the problem better.
//Grabber.h
- #pragma once
- #include "CoreMinimal.h"
- #include "Components/ActorComponent.h"
- #include"Engine/Public/DrawDebugHelpers.h"
- #include"Runtime/Engine/Classes/PhysicsEngine/PhysicsHandleComponent.h"
- #include"Runtime/Engine/Classes/Engine/EngineTypes.h"
- #include"Engine/Classes/Components/InputComponent.h"
- #include"Runtime/Engine/Classes/GameFramework/Actor.h"
- #include "Grabber.generated.h"
- UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
- class BUILDINGESCAPE_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;
- private:
- // How far ahead of the player can we reach in cm
- float Reach = 100.f;
- UPhysicsHandleComponent* PhysicsHandle = nullptr;
- UInputComponent* Inputcomponent = nullptr;
- //Ray-cast and grab what's in reach
- void Grab();
- // Called when grab is released
- void Release();
- // Find (assumed) attached physics handle
- void FindPhysicsHandleComponent();
- // Setup (assumed) attached input component
- void SetupInputComponent();
- // Return hit for first physics body in reach
- const FHitResult GetFirstPhysicsBodyInReach();
- };
- //Grabber.cpp
- #include "Grabber.h"
- #include"Engine/World.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.
- PrimaryComponentTick.bCanEverTick = true;
- // ...
- }
- // Called when the game starts
- void UGrabber::BeginPlay()
- {
- Super::BeginPlay();
- FindPhysicsHandleComponent();
- SetupInputComponent();
- }
- /// Look for attched Physics Handle
- void UGrabber::FindPhysicsHandleComponent()
- {
- PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
- if (PhysicsHandle)
- {
- // Physics Handle is found
- UE_LOG(LogTemp, Warning, TEXT("%s physics handle component"), *GetOwner()->GetName());
- }
- else
- {
- UE_LOG(LogTemp, Error, TEXT("%s missing physics handle component"), *GetOwner()->GetName());
- }
- }
- /// Look for input component (Only appears at runtime)
- void UGrabber::SetupInputComponent()
- {
- Inputcomponent = GetOwner()->FindComponentByClass<UInputComponent>();
- if (Inputcomponent)
- {
- UE_LOG(LogTemp, Warning, TEXT("Input Component available"))
- ///Bind the input action
- Inputcomponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab);
- Inputcomponent->BindAction("Grab", IE_Released, this, &UGrabber::Release);
- }
- else
- {
- UE_LOG(LogTemp, Error, TEXT("Error!! %S missing input Component"), *GetOwner()->GetName())
- }
- }
- void UGrabber::Grab()
- {
- UE_LOG(LogTemp, Warning, TEXT("Grab Pressed"))
- /// LINE TRACE and see if we reach any actor with physics body collision channel set
- auto HitResult = GetFirstPhysicsBodyInReach();
- auto ComponentToGrab = HitResult.GetComponent();
- auto ActorHit = HitResult.GetActor();
- /// If we hit something then attcah a physics handle
- if (ActorHit)
- {
- // Attach a physics handle
- PhysicsHandle->GrabComponentAtLocationWithRotation(
- ComponentToGrab,
- NAME_None,
- ActorHit->GetOwner()->GetActorLocation(),
- ActorHit->GetOwner()->GetActorRotation() // Allow rotation
- );
- }
- }
- void UGrabber::Release()
- {
- UE_LOG(LogTemp, Warning, TEXT("Grab Released"))
- PhysicsHandle->ReleaseComponent();
- }
- // Called every frame
- void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
- {
- Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
- /// Get player viewpoint this tick
- FVector PlayerViewPointLocation;
- FRotator PlayerViewPointRotation;
- GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(OUT PlayerViewPointLocation, OUT PlayerViewPointRotation);
- // Log out to Test
- /*
- UE_LOG(LogTemp, Warning, TEXT("Location : %s , Rotation : %s") , *PlayerViewPointLocation.ToString() , *PlayerViewPointRotation.ToString());
- */
- FVector LineTraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
- // If the physicshnadle is attached
- if (PhysicsHandle->GrabbedComponent)
- {
- // move the object we're holding
- PhysicsHandle->SetTargetLocation(LineTraceEnd);
- }
- }
- const FHitResult UGrabber::GetFirstPhysicsBodyInReach()
- {
- /// Get player viewpoint this tick
- FVector PlayerViewPointLocation;
- FRotator PlayerViewPointRotation;
- GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(OUT PlayerViewPointLocation, OUT PlayerViewPointRotation);
- // Log out to Test
- /*
- UE_LOG(LogTemp, Warning, TEXT("Location : %s , Rotation : %s") , *PlayerViewPointLocation.ToString() , *PlayerViewPointRotation.ToString());
- */
- FVector LineTraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
- /// Setup query params
- FCollisionQueryParams TraceParameters(FName(TEXT("")), false, GetOwner());
- /// Line-trace (AKA ray-cast) out to reach distance
- FHitResult Hit;
- GetWorld()->LineTraceSingleByObjectType(
- OUT Hit,
- PlayerViewPointLocation,
- LineTraceEnd,
- FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
- TraceParameters
- );
- // See what we hit
- AActor* ActorHit = Hit.GetActor();
- if (ActorHit)
- {
- UE_LOG(LogTemp, Warning, TEXT("Line Trace Hit : %s "), *(ActorHit->GetName()))
- }
- return Hit;
- }
Comment