-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInteractorComponent.h
More file actions
251 lines (207 loc) · 10.2 KB
/
InteractorComponent.h
File metadata and controls
251 lines (207 loc) · 10.2 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
// ©2023 JDSherbert. All Rights Reserved.
#pragma once
#include <Runtime/Core/Public/CoreMinimal.h>
#include <Runtime/Engine/Classes/Components/ActorComponent.h>
#include <Runtime/Engine/Classes/GameFramework/HUD.h>
#include <Runtime/Engine/Classes/GameFramework/PlayerController.h>
#include <Runtime/UMG/Public/Blueprint/UserWidget.h>
#include "InteractorComponent.generated.h"
/* ---------------------------- Forward Declarations ----------------------------- */
class AHUD;
class APlayerController;
class UInteractableComponent;
class UInputAction;
class UUserWidget;
/* ------------------------------ Class Definition ------------------------------- */
/**
* Interactor Component Class. Performs behaviors related to interactions.
* Receives input from EnhancedInputSystem Plugin and assigns performs interactions based on definitions in this class.
* Make sure to assign a UInputAction to define the bindings for this behavior!
* @since 19/01/2023
* @author JDSherbert
*/
UCLASS( ClassGroup = "Sherbert", Blueprintable, meta = (BlueprintSpawnableComponent))
class SHERBERT_API UInteractorComponent : public UActorComponent
{
GENERATED_BODY()
public:
UInteractorComponent(const FObjectInitializer& ObjectInitializer);
private:
/** Interact Input Action - Assign bindings here. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Sherbert|Component|Interaction|Input", meta = (AllowPrivateAccess = "true"))
UInputAction* InteractionInputAction;
/* Max distance to use/focus on actors. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sherbert|Component|Interaction", meta = (AllowPrivateAccess = "true"))
float MaxInteractionRange;
/* True only in first frame when focused on new usable actor. */
UPROPERTY(Transient, VisibleInstanceOnly, Category = "Sherbert|Component|Interaction")
bool bHasNewFocus;
/* Actor derived from UsableActor currently in center-view. */
UPROPERTY(Transient, VisibleInstanceOnly, Category = "Sherbert|Component|Interaction")
UInteractableComponent* FocusedInteractableComponent;
/** Turn on logs and lasers. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Sherbert|Component|Interaction", meta = (AllowPrivateAccess = "true"))
bool bDebugMode;
/* The associated player controller. */
UPROPERTY(Transient, VisibleInstanceOnly, Category = "Sherbert|Component|Interaction")
APlayerController* PlayerController;
/* UI to display when an interaction can occur. */
UPROPERTY(EditDefaultsOnly, Category = "Sherbert|Component|Interaction|UI", meta = (AllowPrivateAccess = "true"))
TSubclassOf<UUserWidget> InteractionUITemplate;
UUserWidget* InteractionUIInstance;
/* UI to display when an interaction cannot occur. */
UPROPERTY(EditDefaultsOnly, Category = "Sherbert|Component|Interaction|UI", meta = (AllowPrivateAccess = "true"))
TSubclassOf<UUserWidget> NoInteractionUITemplate;
UUserWidget* NoInteractionUIInstance;
protected:
virtual void BeginPlay() override;
public:
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
protected:
/**
* Initializer method.
* @since 17/01/2023
* @author JDSherbert
*/
void Init();
public:
/**
* Should be called only by an Interactor Component once during initiation.
* Creates a UUserWidget to display cosmetically to the player when an interaction can occur.
* @return UUserWidget* : The interaction widget that was created. Will also be assigned to InteractionUIInstance. Returns nullptr on fail.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "Sherbert|Component|Interaction")
UUserWidget* MakeInteractionUIWidget();
/**
* Should be called only by an Interactor Component once during initiation.
* Creates a UUserWidget to display cosmetically to the player when an interaction cannot occur.
* @return UUserWidget* : The non-interaction widget that was created. Will also be assigned to NoInteractionUIInstance. Returns nullptr on fail.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "Sherbert|Component|Interaction")
UUserWidget* MakeNoInteractionUIWidget();
/**
* Raycast method. Scans for an interactable component on a hit object and returns the currently looked at object.
* Called every tick.
* @return UInteractableComponent* : The Interactable Component that is being looked at.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, Category = "Sherbert|Component|Interaction")
UInteractableComponent* RaycastForInteractable();
/**
* Setter method. Assigns the currently focused interactable component into the cache.
* Invokes OnLookAt event.
* @param NewInteractableComponent : Sets this as the currently focused interactable.
* @return UInteractableComponent* : The Interactable Component that is currently focused.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, Category = "Sherbert|Component|Interaction")
UInteractableComponent* AssignFocusedInteractable(UInteractableComponent* NewInteractableComponent);
/**
* Unsetter method. Unassigns the currently focused interactable component in the cache (sets to nullptr).
* Invokes OnLookAway event.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, Category = "Sherbert|Component|Interaction")
void UnassignFocusedInteractable();
/**
* Display UI method. Cosmetic. Based on input params, will show an interaction or no interaction widget, and hide them when not in use.
* @param bActive : Whether to show or hide the UI Widget.
* @param bCanInteract : If the interactable component is enabled, show the interact UI. Otherwise, show the no interaction UI.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "Sherbert|Component|Interaction")
void DisplayInteractionUIWidget(const bool bActive = false, const bool bCanInteract = true);
/**
* Interaction method. Sends a message to the interactable component on the focused object in a generic way by using events on that component.
* @param Instigator : Should always be "this", or "self". Lets the interactable know who or what is interacting with it.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, Category = "Sherbert|Component|Interaction")
void Interact(UInteractorComponent* Instigator);
/**
* Comparison method. Returns true if the new interactable component is the same as the currently focused interactable in the cache.
* Used to help prevent multiple calls to OnLookAt events on the same interactable.
* @param NewInteractableComponent : The new interactable to compare.
* @return bool : True if NewInteractableComponent matches the cached one.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Sherbert|Component|Interaction")
FORCEINLINE bool CompareInteractable(UInteractableComponent* NewInteractableComponent) { return NewInteractableComponent == FocusedInteractableComponent; }
/**
* Getter method. Returns the first Interactable Component from an actor if one exists.
* @param Actor : The actor to try get the component from.
* @return UInteractableComponent* : The InteractableComponent, if one is found. Otherwise, returns nullptr.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Sherbert|Component|Interaction")
InteractableComponent* GetInteractableComponent(const AActor* Actor);
/**
* Getter method. Returns the owner's HUD, if it has one.
* @return AHUD* : The HUD, if one is found. Otherwise, returns nullptr.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Sherbert|Component|Interaction")
FORCEINLINE AHUD* GetInteractorHUD() const { return GetInteractorPlayerController()->GetHUD(); }
/**
* Getter method. Returns the owner's PlayerController, if it has one.
* @return APlayerController* : The PlayerController, if one is found. Otherwise, returns nullptr.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Sherbert|Component|Interaction")
FORCEINLINE APlayerController* GetInteractorPlayerAgentController() const {return PlayerController; }
/**
* Getter method. Returns the Interaction UI Widget instance, if there is one.
* @return UUserWidget* : The UI Widget, if one is found. Otherwise, returns nullptr.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, BlueprintPure, BlueprintCosmetic, Category = "Sherbert|Component|Interaction")
FORCEINLINE UUserWidget* GetInteractionUIInstance() const { return InteractionUIInstance; }
/**
* Getter method. Returns the No Interaction UI Widget instance, if there is one.
* @return UUserWidget* : The UI Widget, if one is found. Otherwise, returns nullptr.
* @since 27/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintCallable, BlueprintPure, BlueprintCosmetic, Category = "BlueGhost|Component|Interaction")
FORCEINLINE UUserWidget* GetNoInteractionUIInstance() const { return NoInteractionUIInstance; }
/* ------------------------------ Events ------------------------------- */
/**
* Event: Triggers when an interactable component containing object is looked at.
* @param @param Target : The interactable component that is being looked at.
* @since 17/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintImplementableEvent, Category = "Sherbert|Component|Interaction")
void Event_OnLookAt(UInteractableComponent* Target);
/**
* Event: Triggers when an interactable containing object is looked away from.
* @param Target : The interactable component that is being looked away from.
* @since 17/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintImplementableEvent, Category = "Sherbert|Component|Interaction")
void Event_OnLookAway(UInteractableComponent* Target);
/**
* Event: Triggers when the interactable component containing object is interacted with.
* @param Target : The interactable component that is being interacted with.
* @since 17/01/2023
* @author JDSherbert
*/
UFUNCTION(BlueprintImplementableEvent, Category = "Sherbert|Component|Interaction")
void Event_OnInteraction(UInteractableComponent* Target);
};
/* ------------------------------------------------------------------------------- */