Touch Interface Designer 2025.2
Create touch interface with a visual editor and manage all mobile inputs like gestures
Loading...
Searching...
No Matches
ComponentLogic.h
Go to the documentation of this file.
1// Copyright 2024 Lost in Game Studio. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "InputAction.h"
7#include "InputActionValue.h"
8#include "InputTriggers.h"
9#include "UObject/Object.h"
10#include "Layout/Geometry.h"
11#include "Input/Events.h"
12#include "Engine/LocalPlayer.h"
13#include "Framework/Application/SlateApplication.h"
14#include "ComponentLogic.generated.h"
15
19class UInputModifier;
21class UTouchInputComponent;
22class UEnhancedInputLocalPlayerSubsystem;
23class UInputAction;
24class ULayoutComponentDecorator;
25class ULocalPlayer;
26class UForceFeedbackEffect;
27
28USTRUCT(BlueprintType)
30{
31 GENERATED_BODY()
32
33 UPROPERTY(Category="Axis Input Injection", BlueprintReadWrite)
35
36 UPROPERTY(Category="Axis Input Injection", BlueprintReadWrite)
37 float AxisValue;
38
39 UPROPERTY(Category="Axis Input Injection", BlueprintReadWrite)
40 FPlatformUserId UserId;
41
42 UPROPERTY(Category="Axis Input Injection", BlueprintReadWrite)
43 FInputDeviceId InputDeviceId;
44
46 : AxisValue(ForceInitToZero)
47 {
48 UserId = IPlatformInputDeviceMapper::Get().GetPrimaryPlatformUser();
49 InputDeviceId = IPlatformInputDeviceMapper::Get().GetPrimaryInputDeviceForUser(FSlateApplicationBase::SlateAppPrimaryPlatformUser);
50 }
51
52 FAxisInputInjection(const FKey& Key, const float Value, const FPlatformUserId PlatformUserId, const FInputDeviceId DeviceId)
53 : InputKey(Key)
54 , AxisValue(Value)
55 , UserId(PlatformUserId)
56 , InputDeviceId(DeviceId)
57 {
58
59 }
60
61 FAxisInputInjection(const FKey& Key, const float Value, const ULocalPlayer* LocalPlayer)
62 : InputKey(Key)
63 , AxisValue(Value)
64 {
65 UserId = IPlatformInputDeviceMapper::Get().GetPlatformUserForUserIndex(LocalPlayer->GetControllerId());
66 InputDeviceId = IPlatformInputDeviceMapper::Get().GetPrimaryInputDeviceForUser(UserId);
67 }
68};
69
70UENUM(BlueprintType)
77
81UCLASS(Abstract, Blueprintable, BlueprintType, EditInlineNew, /*DefaultToInstanced*/ HideCategories=("Default", "Internal", "InternalUse"))
82class TOUCHINTERFACE_API UComponentLogic : public UObject
83{
84 GENERATED_BODY()
85
86public:
87 UComponentLogic();
88
89 virtual void BeginDestroy() override;
90
91 //TODO: Make pure c++ function that call blueprint function because we need to do safe internal initialization
92
93 //Called when component is initialized
94 UFUNCTION(Category="Layout Component Logic", BlueprintNativeEvent)
95 void Initialize();
96
97 UFUNCTION(Category="Layout Component Logic", BlueprintNativeEvent)
98 void Deinitialize();
99
100 void SetOuter(ULayoutComponent* Outer) { Owner = Outer; }
101 void AssignLocalPlayer(ULocalPlayer* Player, TSharedRef<SLayoutComponent> Widget);
102
103 virtual UWorld* GetWorld() const override;
104
105 bool ShouldTick() const { return bShouldTick; }
106
107 //TODO: Add layout geometry as input?
108 virtual void ProcessPressEvent(const FGeometry& ComponentGeometry, const FGeometry& LayoutGeometry, const FPointerEvent& PointerEvent);
109 virtual void ProcessMoveEvent(const FGeometry& ComponentGeometry, const FGeometry& LayoutGeometry, const FPointerEvent& PointerEvent);
110 virtual void ProcessReleaseEvent(const FGeometry& ComponentGeometry, const FGeometry& LayoutGeometry, const FPointerEvent& PointerEvent);
111 virtual void ProcessTickEvent(const FGeometry& ComponentGeometry, const double InCurrentTime, const float InDeltaTime);
112
113#if WITH_EDITOR
114 virtual void PreviewDecorator();
115#endif
116
117 //TODO: Function that called one to register decorator needed for logic like handle and bar in slider?
118
119protected:
120 virtual void Initialize_Implementation() {}
121 virtual void Deinitialize_Implementation() {}
122
123 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
124 APawn* GetPawn();
125
126 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
127 APlayerController* GetPlayerController();
128
129 //TODO: Add hitbox id and position (for multi hitbox)
130 UFUNCTION(Category="Layout Component Logic", BlueprintNativeEvent)
131 void OnPress(const FGeometry& ComponentGeometry, const FPointerEvent& PointerEvent);
132
133 UFUNCTION(Category="Layout Component Logic", BlueprintNativeEvent)
134 void OnMove(const FGeometry& ComponentGeometry, const FPointerEvent& PointerEvent);
135
136 UFUNCTION(Category="Layout Component Logic", BlueprintNativeEvent)
137 void OnRelease(const FGeometry& ComponentGeometry, const FPointerEvent& PointerEvent);
138
139 UFUNCTION(Category="Layout Component Logic", BlueprintNativeEvent)
140 void OnTick(const FGeometry& ComponentGeometry, const FPointerEvent& PointerEvent, double InCurrentTime, float InDeltaTime);
141
142 virtual void OnPress_Implementation(const FGeometry& ComponentGeometry, const FPointerEvent& PointerEvent) {}
143 virtual void OnMove_Implementation(const FGeometry& ComponentGeometry, const FPointerEvent& PointerEvent) {}
144 virtual void OnRelease_Implementation(const FGeometry& ComponentGeometry, const FPointerEvent& PointerEvent) {}
145 virtual void OnTick_Implementation(const FGeometry& ComponentGeometry, const FPointerEvent& PointerEvent, const double InCurrentTime, const float InDeltaTime) {}
146
147public:
148 TSharedPtr<SLayoutComponent> GetSlotWidget();
149
150 TSharedPtr<STouchInterfaceRuntime> GetLayoutWidget();
151
152 bool IsPressed() const { return bIsPressed; }
153
154 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
155 ULocalPlayer* GetLocalPlayer();
156
157 //Get object that drive slate widget
158 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
159 ULayoutComponent* GetTouchInputObject() const;
160
161 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
162 const FGeometry& GetLastComponentGeometry() const { return LastComponentGeometry; }
163
164 //ENHANCED INPUT
165
166 //Start injecting input (inject input each frame until stop)
167 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
168 void InjectInput(const UInputAction* Action, FInputActionValue RawValue, bool bInjectImmediately = false);
169
170 //Inject input in one frame
171 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
172 void InjectInputInFrame(const UInputAction* Action, FInputActionValue RawValue);
173
174 //Stop injecting input
175 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
176 void StopInjectingInput(const UInputAction* Action);
177
178 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
179 bool IsInputInjected(const UInputAction* Action) const;
180
181 //LEGACY INPUT
182
187 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
188 void InjectActionInput(const FKey& InputKey);
189
190 // Release Action Input
191 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
192 void StopInjectingActionInput(const FKey& InputKey);
193
199 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
200 void InjectAxisInput(const FAxisInputInjection AxisInput, const bool bInjectImmediately = false);
201
202 // Inject input in one frame
203 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
204 void InjectAxisInputInFrame(const FAxisInputInjection AxisInput);
205
206 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
207 void StopInjectingAxisInput(FKey AxisInput);
208
209 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
210 void StopInjectingAxisInputByName(const FName InputName);
211
212 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
213 FAxisInputInjection CreateAxisInputInjectionForPlayer(FKey Key, const float Value);
214
218 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintNativeEvent)
219 void SetInputAction(UInputAction* NewInputAction);
220
221 //Enable input. This logic will now process inputs.
222 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
223 virtual void EnableInput() { bBlockInput = false; }
224
225 //Disable input. This logic will not process inputs.
226 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
227 virtual void DisableInput() { bBlockInput = true; }
228
229 //Return true if this logic process inputs
230 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
231 virtual bool IsInputEnabled() { return !bBlockInput; }
232
233
234 //TODO: Process Gesture (UObject Gesture)?
235
236
237 //TICK
238
239 //Enable tick on this logic
240 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
241 void EnableTick();
242
245 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
246 void DisableTick();
247
248
249 // EFFECTS
250
251 //TODO: Force feedback effect on move and end?
252
253 //TODO: Little force when joystick thumb move?
254
255 //Simple function to play UI sound
256 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
257 void PlaySound(USoundBase* Sound);
258
259 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
260 void PlaySimpleHaptic(const float Duration = 0.05f, const float Intensity = 0.3f, const bool bAffectLarge = true, const bool bAffectSmall = true);
261
262 //Simple function to trigger a vibration
263 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
264 void PlayHaptic(UForceFeedbackEffect* ForceFeedbackEffect, bool bLooping, bool bIgnoreTimeDilation, bool bPlayWhilePaused);
265
266 //Stop vibration
267 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
268 void StopHaptic(UForceFeedbackEffect* ForceFeedbackEffect);
269
270 //Return true if a vibration is being processed
271 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
272 bool IsHapticPlayed(UForceFeedbackEffect* ForceFeedbackEffect);
273
274 bool ContainPointerIndex(int32 PointerIndex) const;
275
276protected:
277 //Get Enhanced input local player subsystem
278 UFUNCTION(Category="Layout Component Logic", BlueprintCallable)
279 UEnhancedInputLocalPlayerSubsystem* GetEnhancedInputSubsystem();
280
281 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
282 FVector2D GetHitLocationFromCenter(const bool bNormalize, bool bConvertToWorldSpace = false);
283
284 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
285 FVector2D GetLocalHitLocation(const bool bNormalized);
286
287 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
288 FVector2D GetAbsoluteHitLocation();
289
290 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
291 FVector2D GetHitLocation(const EHitLocationSpace Space, const bool bNormalized);
292
293 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
294 ULayoutComponent* GetLayoutComponent() const { return Owner; }
295
296 //Clamp offset to the ellipse of the component. Useful for thumbstick of joystick
297 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
298 FVector2D ClampOffsetToEllipse(const FVector2D Offset, const FVector2D ComponentSize);
299
300 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
301 FVector2D GetNormalizedOffset(const FVector2D LocalPosition, const FVector2D ComponentSize);
302
303 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
304 bool IsOrientedInDirection(const FVector2D Direction, const FVector2D Other, const float Threshold) const;
305
306 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
307 float GetAngleBetweenVector(const FVector2D VectorA, const FVector2D VectorB, const bool bSignedAngle = true, const bool bInvert = false);
308
309 UFUNCTION(Category="Layout Component Logic", BlueprintCallable, BlueprintPure)
310 float ConvertSignedAngleTo360(const float SignedAngle);
311
312 //TODO: Lock Input at desired value
313
314 //TODO: Lock decorator to desired position
315
316 //TODO: Unlock input
317
318 //TODO: IsLocked
319
320 //TODO: Convert to world space
321
322 // UTILITIES
323
324 UFUNCTION(Category="LayoutComponentLogic|Utility", BlueprintCallable, BlueprintPure, meta=(CompactNodeTitle="CheckName"))
325 bool CheckNameValidity(const FName Name) const;
326
327 UFUNCTION()
328 TArray<FName> GetAllDecoratorNames() const;
329
330protected:
333 UPROPERTY(Category="Layout Component", BlueprintReadOnly, EditDefaultsOnly, meta=(AllowPrivateAccess="true"))
334 bool bShouldTick;
335
336public:
339 UPROPERTY(Category="Layout Component", EditAnywhere, BlueprintReadWrite, Instanced)
340 TArray<TObjectPtr<UInputTrigger>> InputTriggers;
341
342 //TODO: Doesn't work with EditInstanceOnly
343 //UPROPERTY(Category="Touch Logic", EditAnywhere, BlueprintReadWrite, Instanced)
344 //TArray<TObjectPtr<UInputModifier>> InputModifiers;
345
348 UPROPERTY(Category="Layout Component", EditAnywhere, BlueprintReadWrite, Instanced)
349 TArray<TObjectPtr<ULCInputModifier>> InputModifiers;
350
351 //TODO: Decorator to drive (Array or use group)
352
353
354private:
355 UPROPERTY()
356 UWorld* WorldContext;
357
358 UPROPERTY()
359 ULocalPlayer* LocalPlayer;
360
361 UPROPERTY()
362 UEnhancedInputLocalPlayerSubsystem* InputSubsystem;
363
364 UPROPERTY()
365 TObjectPtr<ULayoutComponent> Owner;
366
367 TSharedPtr<SLayoutComponent> OwnerWidget;
368
369 FPointerEvent LastPointerEvent;
370
371 FGeometry LastComponentGeometry;
372
373 FGeometry LastLayoutGeometry;
374
375 UPROPERTY()
376 TMap<const UInputAction*, FInputActionValue> InjectedInputs;
377
378 TArray<FAxisInputInjection> InjectedAxis;
379
380 //Currently pressed by user
381 uint8 bIsPressed:1;
382
383 //Pressed event has been sent
384 uint8 bHasStarted:1;
385
386 //Do not send touch event
387 uint8 bBlockInput:1;
388
389 TArray<int32> ActivePointerIndex;
390
391 FVector2D LastLocalCoord;
392};
EditInlineNew
Definition ComponentDecorator_Animation.h:40
Abstract
Definition ComponentDecorator_Animation.h:40
BlueprintType
Definition ComponentDecorator_Animation.h:40
HideCategories
Definition ComponentDecorator_Animation.h:40
@ OnPress
Definition ComponentDecorator_Animation.h:17
@ OnRelease
Definition ComponentDecorator_Animation.h:20
Blueprintable
Definition ComponentDecorator_Animation.h:40
EHitLocationSpace
Definition ComponentLogic.h:72
@ LocalSpace
Definition ComponentLogic.h:73
@ ViewportSpace
Definition ComponentLogic.h:75
@ LayoutSpace
Definition ComponentLogic.h:74
meta
Definition GestureRecognizerComp.h:274
Definition SLayoutComponent.h:55
Definition STouchInterfaceRuntime.h:30
Definition LCInputModifier.h:18
Definition LayoutComponent.h:94
Definition ComponentLogic.h:30
FAxisInputInjection(const FKey &Key, const float Value, const FPlatformUserId PlatformUserId, const FInputDeviceId DeviceId)
Definition ComponentLogic.h:52
FAxisInputInjection(const FKey &Key, const float Value, const ULocalPlayer *LocalPlayer)
Definition ComponentLogic.h:61
BlueprintReadWrite FPlatformUserId UserId
Definition ComponentLogic.h:40
Category
Definition ComponentLogic.h:33
BlueprintReadWrite float AxisValue
Definition ComponentLogic.h:37
BlueprintReadWrite FInputDeviceId InputDeviceId
Definition ComponentLogic.h:43
FAxisInputInjection()
Definition ComponentLogic.h:45
BlueprintReadWrite FKey InputKey
Definition ComponentLogic.h:34