for some reason when im trying to compile my code for the “crypt raider” tutorial, it is telling me that “PhysicsHandle” is an undeclaired identifier, however my header file already includes “PhysicsEngine/PhysicsHandleComponent.h”
here’s both the cpp and header files for
Grabber.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/SceneComponent.h"
#include "PhysicsEngine/PhysicsHandleComponent.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 Grab();
UFUNCTION(BlueprintCallable)
void Release();
private:
UPROPERTY(EditAnywhere)
float MaxGrabDistance = 400;
UPROPERTY(EditAnywhere)
float GrabRadius = 100;
UPROPERTY(EditAnywhere)
float HoldDistance = 200;
UPhysicsHandleComponent* GetPhysicsHandle() const;
bool GetGrabbableInReach(FHitResult& OutHitResult) const;
};
Grabber.cpp:
// Fill out your copyright notice in the Description page of Project Settings.
#include "Grabber.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.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();
}
// Called every frame
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (PhysicsHandle && PhysicsHandle->GetGrabbedComponent())
{
FVector TargetLocation = GetComponentLocation() + GetForwardVector() * HoldDistance;
PhysicsHandle->SetTargetLocationAndRotation(TargetLocation, GetComponentRotation());
}
}
void UGrabber::Grab()
{
UPhysicsHandleComponent* PhysicsHandle = GetPhysicsHandle();
if (PhysicsHandle == nullptr)
{
return;
}
FHitResult HitResult;
bool HasHit = GetGrabbableInReach(HitResult);
if (HasHit)
{
UPrimitiveComponent* HitComponent = HitResult.GetComponent();
HitComponent->WakeAllRigidBodies();
HitResult.GetActor()->Tags.Add("Grabbed");
PhysicsHandle->GrabComponentAtLocationWithRotation(
HitComponent,
NAME_None,
HitResult.ImpactPoint,
GetComponentRotation()
);
}
}
void UGrabber::Release()
{
UPhysicsHandleComponent* PhysicsHandle = GetPhysicsHandle();
if (PhysicsHandle && PhysicsHandle->GetGrabbedComponent())
{
AActor* GrabbedActor = PhysicsHandle->GetGrabbedComponent()->GetOwner();
GrabbedActor->Tags.Remove("Grabbed");
PhysicsHandle->ReleaseComponent();
}
}
UPhysicsHandleComponent* UGrabber::GetPhysicsHandle() const
{
UPhysicsHandleComponent* Result = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
if (Result == nullptr)
{
UE_LOG(LogTemp, Error, TEXT("Grabber Requires A UPhysicsHandleComponent"));
}
return Result;
}
bool UGrabber::GetGrabbableInReach(FHitResult& OutHitResult) const
{
FVector Start = GetComponentLocation();
FVector End = Start + GetForwardVector() * MaxGrabDistance;
DrawDebugLine(GetWorld(), Start, End, FColor::Purple);
DrawDebugSphere(GetWorld(), End, 10, 10, FColor::Blue, false, 5);
FCollisionShape Sphere = FCollisionShape::MakeSphere(GrabRadius);
return GetWorld()->SweepSingleByChannel(
OutHitResult,
Start, End,
FQuat::Identity,
ECC_GameTraceChannel2,
Sphere);
}