// Copyright Epic Games, Inc. All Rights Reserved. #include "UI/LyraJoystickWidget.h" #include "Components/Image.h" #include "Input/Events.h" #include "Layout/Geometry.h" #include "Math/UnrealMathUtility.h" #include "Templates/SharedPointer.h" #define LOCTEXT_NAMESPACE "LyraJoystick" ULyraJoystickWidget::ULyraJoystickWidget(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { SetConsumePointerInput(true); } FReply ULyraJoystickWidget::NativeOnTouchStarted(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent) { Super::NativeOnTouchStarted(InGeometry, InGestureEvent); TouchOrigin = InGestureEvent.GetScreenSpacePosition(); FReply Reply = FReply::Handled(); if (!HasMouseCaptureByUser(InGestureEvent.GetUserIndex(), InGestureEvent.GetPointerIndex())) { Reply.CaptureMouse(GetCachedWidget().ToSharedRef()); } return Reply; } FReply ULyraJoystickWidget::NativeOnTouchMoved(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent) { Super::NativeOnTouchMoved(InGeometry, InGestureEvent); HandleTouchDelta(InGeometry, InGestureEvent); FReply Reply = FReply::Handled(); if (!HasMouseCaptureByUser(InGestureEvent.GetUserIndex(), InGestureEvent.GetPointerIndex())) { Reply.CaptureMouse(GetCachedWidget().ToSharedRef()); } return Reply; } FReply ULyraJoystickWidget::NativeOnTouchEnded(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent) { StopInputSimulation(); return FReply::Handled().ReleaseMouseCapture(); } void ULyraJoystickWidget::NativeOnMouseLeave(const FPointerEvent& InMouseEvent) { Super::NativeOnMouseLeave(InMouseEvent); StopInputSimulation(); } void ULyraJoystickWidget::NativeTick(const FGeometry& MyGeometry, float InDeltaTime) { Super::NativeTick(MyGeometry, InDeltaTime); // Move the inner stick icon around with the vector if (JoystickForeground && JoystickBackground) { JoystickForeground->SetRenderTranslation( (bNegateYAxis ? FVector2D(1.0f, -1.0f) : FVector2D(1.0f)) * StickVector * (JoystickBackground->GetDesiredSize() * 0.5f) ); } InputKeyValue2D(StickVector); } void ULyraJoystickWidget::HandleTouchDelta(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent) { const FVector2D& ScreenSpacePos = InGestureEvent.GetScreenSpacePosition(); // The center of the geo locally is just its size FVector2D LocalStickCenter = InGeometry.GetAbsoluteSize(); FVector2D ScreenSpaceStickCenter = InGeometry.LocalToAbsolute(LocalStickCenter); // Get the offset from the origin FVector2D MoveStickOffset = (ScreenSpacePos - ScreenSpaceStickCenter); if (bNegateYAxis) { MoveStickOffset *= FVector2D(1.0f, -1.0f); } FVector2D MoveStickDir = FVector2D::ZeroVector; float MoveStickLength = 0.0f; MoveStickOffset.ToDirectionAndLength(MoveStickDir, MoveStickLength); MoveStickLength = FMath::Min(MoveStickLength, StickRange); MoveStickOffset = MoveStickDir * MoveStickLength; StickVector = MoveStickOffset / StickRange; } void ULyraJoystickWidget::StopInputSimulation() { TouchOrigin = FVector2D::ZeroVector; StickVector = FVector2D::ZeroVector; } #undef LOCTEXT_NAMESPACE