给 DefaultPawn_Blueprint 添加组件 Phusics Handle
(对蓝图做的修改都要保存和编译)添加完组件后,需要 Save 和 编译
使用Physics Handle 需要引入的头文件 #include "PhysicsEngine/PhysicsHandleComponent.h"
不知道用头文件,使用谷歌搜索一下,看官方的文档里面找
使用 UPhysicsHandleComponent* ,需要引入头文件 #include "PhysicsEngine/PhysicsHandleComponent.h"
没有引入组件导致的报错:
引入#include "Components/PrimitiveComponent.h"
使用UPrimitiveComponent* 需要引入 #include "Components/PrimitiveComponent.h"
没有抓起来,Actor是 可移动的
// Grabber.h
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Components/InputComponent.h"
#include "PhysicsEngine/PhysicsHandleComponent.h"
#include "Grabber.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class UNREALENGINEPROJECT_API UGrabber : public UActorComponent
{
GENERATED_BODY()
public:
UGrabber();
protected:
virtual void BeginPlay() override;
public:
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
private:
FVector GetLineStart();
FVector GetLineEnd();
FHitResult LineTrace();
UInputComponent* InputComponent = nullptr;
UPhysicsHandleComponent* PhysicsHandle = nullptr;
void Grab();
void Release();
};
// Grabber.cpp
#include "Grabber.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.h"
#include "Components/PrimitiveComponent.h"
UGrabber::UGrabber()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UGrabber::BeginPlay()
{
Super::BeginPlay();
PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
if (InputComponent)// 使用指针需要判断不为空
{
UE_LOG(LogTemp, Warning, TEXT("Input Component is founded!"));
InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab);
InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::Release);
}
else
{
UE_LOG(LogTemp, Error, TEXT("Input Component is not founded!"));
}
}
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}
FVector UGrabber::GetLineStart()
{
FVector Start;
FRotator ViewRotator;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(Start, ViewRotator);
return Start;
}
FVector UGrabber::GetLineEnd()
{
FVector Start;
FRotator ViewRotator;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(Start, ViewRotator);
return (Start + ViewRotator.Vector() * 100); // ViewRotator.Vector() 视野的正中心 前方 100cm
}
FHitResult UGrabber::LineTrace()
{
//DrawDebugLine(GetWorld(), Start, End, FColor(255, 0, 0), false, 0, 0, 10);
FHitResult Hit;
GetWorld()->LineTraceSingleByObjectType(
Hit,
GetLineStart(),
GetLineEnd(),
FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
FCollisionQueryParams(FName(TEXT("")), false, GetOwner())
);
AActor* Actor = Hit.GetActor();
if (Actor != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Line Hit:%s"), *Actor->GetName());
}
return Hit;
}
void UGrabber::Grab()
{
UE_LOG(LogTemp, Warning, TEXT("Grab action is pressed!"));
FHitResult Hit = LineTrace();
UPrimitiveComponent* ComponentToGrab = Hit.GetComponent();
if (Hit.GetActor() && PhysicsHandle)
{
UE_LOG(LogTemp, Warning, TEXT("Grab!"));
//PhysicsHandle->GrabComponent(ComponentToGrab, NAME_None, ComponentToGrab->GetOwner()->GetActorLocation(), true); // 已弃用
PhysicsHandle->GrabComponentAtLocation(ComponentToGrab, NAME_None, ComponentToGrab->GetOwner()->GetActorLocation());
}
}
void UGrabber::Release()
{
UE_LOG(LogTemp, Error, TEXT("Grab action is released!"));
}