Hi guys,
So, by now I’ve watched the Video several Times, and am pretty sure I did everything as supossed.
The Problem is, When I try grabbing something, nothing happens.
When starting to Play, UE gives me a Warning “Attempting to release an actor with a null handle” but I have no Idea what this is referring to. The PhysicsHandle cant be null with the safety return, right?
Edit: Just saw the log seems to have something to do with the Chaos System
Logging the Name of the HitResult works perfectly fine, so I assume it would be something with the Target Location, but I have absolutely no Idea what could be the Problem.
Google spits out some stuff about actual nullpointers, and something about PhysicsHandle in UE5 being buggy, but I’m way too unexperienced to get something out of that information.
Would be awesome if anyone can help out with this.
Here is my Code for Reference:
Header:
#pragma once
#include "CoreMinimal.h"
#include "Components/SceneComponent.h"
#include "Grabber.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class CRYPTRAIDER_API UGrabber : public USceneComponent
{
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;
UFUNCTION(BlueprintCallable)
void Release();
UFUNCTION(BlueprintCallable)
void Grab();
private:
UPROPERTY(EditAnywhere)
float MaxGrabDistance = 400;
UPROPERTY(EditAnywhere)
float GrabRadius = 100;
UPROPERTY(EditAnywhere)
float HoldDistance = 200;
};
CPP:
#include "Grabber.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.h"
#include "PhysicsEngine/PhysicsHandleComponent.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();
UPhysicsHandleComponent* PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
if(PhysicsHandle == nullptr){
return;
}
}
// Called every frame
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
UPhysicsHandleComponent* PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
if(PhysicsHandle == nullptr){
return;
}
FVector TargetLocation = GetComponentLocation() + GetForwardVector() * HoldDistance;
PhysicsHandle->SetTargetLocationAndRotation(TargetLocation, GetComponentRotation());
}
void UGrabber::Grab()
{
UPhysicsHandleComponent* PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
if(PhysicsHandle == nullptr){
return;
}
FVector Start = GetComponentLocation();
FVector End = Start + GetForwardVector() * MaxGrabDistance;
DrawDebugLine(GetWorld(), Start, End, FColor::Red);
FCollisionShape Sphere = FCollisionShape::MakeSphere(GrabRadius);
FHitResult HitResult;
bool HasHit = GetWorld()->SweepSingleByChannel(HitResult, Start, End, FQuat::Identity, ECC_GameTraceChannel2, Sphere);
if(HasHit){
PhysicsHandle->GrabComponentAtLocationWithRotation(HitResult.GetComponent(), NAME_None, HitResult.ImpactPoint, GetComponentRotation());
UE_LOG(LogTemp, Warning, TEXT("HasHit"));
}
}
void UGrabber::Release()
{
UE_LOG(LogTemp, Warning, TEXT("Released Grabber"));
}