-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGrabber.cpp
More file actions
106 lines (93 loc) · 3.13 KB
/
Grabber.cpp
File metadata and controls
106 lines (93 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#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);
UPhysicsHandleComponent* PhysicsHandle = GetPhysicsHandle();
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->SetSimulatePhysics(true);
HitComponent->WakeAllRigidBodies();
AActor* HitActor = HitResult.GetActor();
HitActor->Tags.Add("Grabbed");
HitActor->DetachFromActor(FDetachmentTransformRules::KeepWorldTransform);
PhysicsHandle->GrabComponentAtLocationWithRotation(
HitComponent,
NAME_None,
HitResult.ImpactPoint,
GetComponentRotation()
);
//DrawDebugSphere(GetWorld(),HitResult.Location, 10, 10, FColor::Green, false, 5);
//DrawDebugSphere(GetWorld(),HitResult.ImpactPoint, 10, 10, FColor::Red, false, 5);
//AActor *HitActor = HitResult.GetActor();
//UE_LOG(LogTemp, Display, TEXT("Hit Actor: %s"), *HitActor->GetActorNameOrLabel());
}
else
{
UE_LOG(LogTemp, Display, TEXT("No Actor Hit"));
}
}
void UGrabber::Release()
{
UPhysicsHandleComponent* PhysicsHandle = GetPhysicsHandle();
if (PhysicsHandle && PhysicsHandle->GetGrabbedComponent() != nullptr)
{
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 UPhysicsComponent"));
}
return Result;
}
bool UGrabber::GetGrabbableInReach(FHitResult& OutHitResult) const
{
FVector Start = GetComponentLocation();
FVector End = Start + GetForwardVector() * MaxGrabDistance;
DrawDebugLine(GetWorld(), Start, End, FColor::Red);
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);
}