/
UxtFarCursorComponent.cpp
122 lines (99 loc) · 3.29 KB
/
UxtFarCursorComponent.cpp
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "Controls/UxtFarCursorComponent.h"
#include "Input/UxtFarPointerComponent.h"
#include "GameFramework/Actor.h"
#include "Utils/UxtFunctionLibrary.h"
#include "UXTools.h"
UUxtFarCursorComponent::UUxtFarCursorComponent()
{
PrimaryComponentTick.bCanEverTick = true;
RingThickness = 0.64f;
BorderThickness = 0.08f;
// Will start ticking when the far pointer is enabled
PrimaryComponentTick.bStartWithTickEnabled = false;
SetHiddenInGame(true);
}
void UUxtFarCursorComponent::BeginPlay()
{
Super::BeginPlay();
auto Owner = GetOwner();
UUxtFarPointerComponent* FarPointer = Owner->FindComponentByClass<UUxtFarPointerComponent>();
if (FarPointer)
{
FarPointerWeak = FarPointer;
// Tick after the pointer so we use its latest state
AddTickPrerequisiteComponent(FarPointer);
// Activate now if the pointer is enabled
if (FarPointer->IsEnabled())
{
OnFarPointerEnabled(FarPointer);
}
// Subscribe to state changes
FarPointer->OnFarPointerEnabled.AddDynamic(this, &UUxtFarCursorComponent::OnFarPointerEnabled);
FarPointer->OnFarPointerDisabled.AddDynamic(this, &UUxtFarCursorComponent::OnFarPointerDisabled);
}
else
{
UE_LOG(UXTools, Error, TEXT("Could not find a far pointer in actor '%s'. Far cursor won't work properly."), *Owner->GetName());
}
}
void UUxtFarCursorComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
if (UUxtFarPointerComponent* FarPointer = FarPointerWeak.Get())
{
FarPointer->OnFarPointerEnabled.RemoveDynamic(this, &UUxtFarCursorComponent::OnFarPointerEnabled);
FarPointer->OnFarPointerDisabled.RemoveDynamic(this, &UUxtFarCursorComponent::OnFarPointerDisabled);
}
}
void UUxtFarCursorComponent::OnFarPointerEnabled(UUxtFarPointerComponent* FarPointer)
{
SetActive(true);
SetHiddenInGame(false);
}
void UUxtFarCursorComponent::OnFarPointerDisabled(UUxtFarPointerComponent* FarPointer)
{
SetActive(false);
SetHiddenInGame(true);
SetPressed(false);
}
void UUxtFarCursorComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (UUxtFarPointerComponent* FarPointer = FarPointerWeak.Get())
{
// Place hovering the hit location
const auto HitNormal = FarPointer->GetHitNormal();
FVector Location = FarPointer->GetHitPoint() + HitNormal * HoverDistance;
SetWorldLocation(Location);
// Align with hit normal
const FMatrix Rotation = FRotationMatrix::MakeFromX(-HitNormal);
SetWorldRotation(Rotation.ToQuat());
// Update pressed state
SetPressed(FarPointer->IsPressed());
// Scale with distance to head
float DistanceToCamera = (UUxtFunctionLibrary::GetHeadPose(this).GetTranslation() - Location).Size();
float ReferenceDistance = 100.0f;
float NewRadius = bPressed ? PressedRadius : IdleRadius;
NewRadius *= DistanceToCamera / ReferenceDistance;
SetRadius(NewRadius);
}
}
void UUxtFarCursorComponent::SetPressed(bool bNewPressed)
{
if (bNewPressed != bPressed)
{
bPressed = bNewPressed;
if (bPressed)
{
// Cache current thickness so we can restore it when released
IdleRingThickness = GetRingThickness();
SetRingThickness(1.0f);
}
else
{
SetRingThickness(IdleRingThickness);
}
}
}