Files
PHY/Plugins/GGS/Source/GenericUISystem/Private/UI/Mobile/GUIS_JoystickWidget.cpp
2026-03-03 01:23:02 +08:00

109 lines
3.1 KiB
C++

// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
#include "UI/Mobile/GUIS_JoystickWidget.h"
#include "CommonHardwareVisibilityBorder.h"
#include "Components/Image.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(GUIS_JoystickWidget)
#define LOCTEXT_NAMESPACE "GUIS_Joystick"
UGUIS_JoystickWidget::UGUIS_JoystickWidget(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
SetConsumePointerInput(true);
}
FReply UGUIS_JoystickWidget::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 UGUIS_JoystickWidget::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 UGUIS_JoystickWidget::NativeOnTouchEnded(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent)
{
StopInputSimulation();
return FReply::Handled().ReleaseMouseCapture();
}
void UGUIS_JoystickWidget::NativeOnMouseLeave(const FPointerEvent& InMouseEvent)
{
Super::NativeOnMouseLeave(InMouseEvent);
StopInputSimulation();
}
void UGUIS_JoystickWidget::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
Super::NativeTick(MyGeometry, InDeltaTime);
if (!CommonVisibilityBorder || CommonVisibilityBorder->IsVisible())
{
// 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 UGUIS_JoystickWidget::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 UGUIS_JoystickWidget::StopInputSimulation()
{
TouchOrigin = FVector2D::ZeroVector;
StickVector = FVector2D::ZeroVector;
}
#undef LOCTEXT_NAMESPACE