Unreal Engine Crash On Using Physics Handle

I am not sure if someone will reply or not as i have tried posting this on many forum and none of them helped. Whenever i try to use physics handle in my Grabber.cpp my unreal crashes. I don’t know why. I have tried adding ensure() but even then it doesn’t works. I am following Unreal C++ Beginner Course by Ben and Sam and i’ve come here with one last hope. Any help is hugely appreciated. I am posting a part of my code where the unreal crashes below:

if (ActorHit)
{
if(ensure(PhysicsHandle!=nullptr))
{
// Attach a physics handle
PhysicsHandle->GrabComponentAtLocationWithRotation(
ComponentToGrab,
NAME_None,
ActorHit->GetOwner()->GetActorLocation(),
ActorHit->GetOwner()->GetActorRotation() // Allow rotation
);
}
}

in the above code, as son as unreal reaches

PhysicsHandle->GrabComponentAtLocationWithRotation

it crashes, If i comment out that section, everything works fine. I am also attaching my header and .cpp file just in case you need a look.

Grabber.h

// Fill out your copyright notice in the Description page of Project Settings.

#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();

};

Grabeer.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#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();

if (PhysicsHandle)
{
	// Physics Handle is found
	UE_LOG(LogTemp, Warning, TEXT("%s physics handle component available"), *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();

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)
	{
		if(ensure(PhysicsHandle!=nullptr))
		{
			// 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;

}

Thank you in advance guys,i have been trying to find out the cause of error since past 3 days and finally I have come here with very high hope.

1 Like

That’s incredibly hard to read, please use the code formatting button </>

1 Like

I am really sorry i didn’t know about the formatting stuff, I’ve registered in the fourm today itself.


I am trying again to post the code with the formatting you suggested. hope it works. I am also attaching a screenshot of an error that i later discovered while in debug mode, Maybe that could help you understand the problem.

Grabber.h

<
// Fill out your copyright notice in the Description page of Project Settings.

	#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

<
// Fill out your copyright notice in the Description page of Project Settings.

	#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 available"), *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)
			{
				if(ensure(PhysicsHandle!=nullptr))
				{
					// 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;
	}

/>

Sorry I was referring to this button
tv
Not that you surround the code with </>. For formatting you either indent the code by 4 spaces or surround it with three backticks e.g.

```
code goes here
```


That screenshot helps a lot, the call stacks says you are in AActor::GetActorRotation so that would suggest that maybe what you’re calling that on is nullptr.
The problem is that you are using ActorHit which is an AActor* meaning doing this

ActorHit->GetOwner()->GetActorLocation(),
ActorHit->GetOwner()->GetActorRotation() // Allow rotation

Is problematic since that actor doesn’t have an owner so would return nullptr. I would suggest you use ComponentHit->GetComponentLocation() instead.

Thank You, Thank You very much. That solved my problem. However that raised another doubt in my mind. You said that actor doesn’t have an owner. I am confused, ActorHit should have the actor that we hit (Pointer to an actor), but it doesn’t have an owning Actor?? Why is it so? Do you mean to say is that Pointer to and actor doesn’t have an Owner?? If so then how was i able to use ActorHit->GetOwner()
Souldn’t that be restricted if that was the case. But that didn’t happen, I was able to use ActorHit->GetOwner()->(and i could access any function from getowner here as intellisense was recognizing many functions here) so that means i was able to use GetOwner() whisch means GetOwner Exists, Its not null, Right?? It’s confusing. Please help me understand this. Where am i getting this wrong?? My game is back to working but this partcular concept is confusing me.

Correct. because nothing owns it. Consider a character with a gun, the character being an ACharacter and the gun an AActor. You would set that gun to have its owner be the character but the character wouldn’t have an owner as its independant, nothing owns it nor would it make sense (in a typical FPS) for it to have one.
We’ve been using GetOwner on components which has the owner be the AActor that it’s attached to.

If you mean to say it doesn’t have the function GetOwner() then no.

Just because it has the function doesn’t mean the pointer that is returned isn’t null. How could the compiler know at compile time whether the pointer is null or not?

I dont understand this part. Can you please explain this again. I hope i am not annoying you, but i am new to all this and it’s confusing.

By default an AActor doesn’t have an owner like a component would (would be the actor that the component is attached to).

Imagine a typical FPS, you could have the gun as an actor that is spawned in the world and then the character could pick that gun up. And then upon pickup the guns owner is set to the character that picked it up.

https://docs.unrealengine.com/en-US/Gameplay/Networking/Actors/OwningConnections/index.html

Also, not annoying :slight_smile:

1 Like

So what you are saying is that when i was hitting a table earlier(when the crash was happening), The ActorHit->GetOwner()->GetLocation() was returning a null pointer beacause it was assigned like this:

ActorHit = HitResult.GetActor()

which was returning SM_Table in ActorHit but then ActorHit->GetOwner() would return null when ActorHit->GetOwner()->GetLocation() was executed because ActorHit i.e. SM_Table didn’t had an Owning Actor by default.

Is that what you mean?? Did I get it right?

Correct :slight_smile: . It was never assigned an owner.

One last doubt, more like confirmation if i am not missing anything, so in essence

ActorHit->GetOwner()->GetLocation()

was like nullptr->GetLocation()

as ActorHit->GetOwner() was fetching nullptr

right??

@DanM Did i get it right??

Yes.

Alright, This is an amazing forum and you are amazing instructor. Thanks for helping me figure this out. I really appreciate your help :blush:

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.