添加可拖拽UI

This commit is contained in:
997146918 2025-11-02 14:29:35 +08:00
parent 0513ccc3d7
commit 253df874a3
91 changed files with 205 additions and 4 deletions

View File

@ -2,7 +2,7 @@
"BuildId": "37670630",
"Modules":
{
"ProjectFish": "UnrealEditor-ProjectFish.dll",
"ProjectFishEditor": "UnrealEditor-ProjectFishEditor.dll"
"ProjectFish": "UnrealEditor-ProjectFish-0027.dll",
"ProjectFishEditor": "UnrealEditor-ProjectFishEditor-0027.dll"
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,6 +2,6 @@
"BuildId": "37670630",
"Modules":
{
"DeskMode": "UnrealEditor-DeskMode.dll"
"DeskMode": "UnrealEditor-DeskMode-0027.dll"
}
}

View File

@ -0,0 +1,16 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "UIManagerSubsystem.h"
#include "ProjectFish/Widget/DragableUserWidget.h"
void UUIManagerSubsystem::AddDragWidget(UDragableUserWidget* UserWidget)
{
DragDropWidget = MakeWeakObjectPtr(UserWidget);
}
void UUIManagerSubsystem::RemoveDragWidget()
{
DragDropWidget.Reset();
}

View File

@ -0,0 +1,28 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "Widgets/SWidget.h"
#include "Blueprint/UserWidget.h"
#include "UIManagerSubsystem.generated.h"
/**
*
*/
UCLASS()
class PROJECTFISH_API UUIManagerSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "UIManagerSubsystem")
void AddDragWidget(class UDragableUserWidget* UserWidget);
UFUNCTION(BlueprintCallable, Category = "UIManagerSubsystem")
void RemoveDragWidget();
protected:
TWeakObjectPtr<class UDragableUserWidget> DragDropWidget;
};

View File

@ -9,6 +9,6 @@ public class ProjectFish : ModuleRules
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
OptimizeCode = CodeOptimization.Never;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine",
"InputCore", "NavigationSystem", "AIModule", "Niagara", "EnhancedInput", "GameplayTags", "DeveloperSettings" });
"InputCore", "NavigationSystem", "AIModule", "Niagara", "EnhancedInput", "GameplayTags", "DeveloperSettings", "UMG", "Slate" ,"SlateCore"});
}
}

View File

@ -0,0 +1,120 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "DragableUserWidget.h"
#include "Blueprint/WidgetLayoutLibrary.h"
#include "Components/CanvasPanelSlot.h"
#include "ProjectFish/Gameplay/Subsystem/UIManagerSubsystem.h"
void UDragableUserWidget::SetWidgetDragable(bool Dragable)
{
bDragable = Dragable;
}
void UDragableUserWidget::BeginDrag(const FGeometry& InGeometry)
{
bDraging = true;
OriginWidgetScreenPos = InGeometry.GetAbsolutePosition();
UUIManagerSubsystem* UIManager = GetGameInstance()->GetSubsystem<UUIManagerSubsystem>();
UIManager->AddDragWidget(this);
}
void UDragableUserWidget::EndDrag()
{
//取消拖拽 不处理点击事件
bDraging = false;
UUIManagerSubsystem* UIManager = GetGameInstance()->GetSubsystem<UUIManagerSubsystem>();
UIManager->RemoveDragWidget();
}
FReply UDragableUserWidget::NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
if (bDragable && InMouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
{
if (bDraging)
{
EndDrag();
return FReply::Unhandled();
}
else
{
BeginDrag(InGeometry);
return FReply::Handled();
}
}
else
{
return Super::NativeOnMouseButtonDown(InGeometry, InMouseEvent);
}
}
FReply UDragableUserWidget::NativeOnMouseButtonUp(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
return Super::NativeOnMouseButtonUp(InGeometry, InMouseEvent);
}
FReply UDragableUserWidget::NativeOnMouseMove(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
if (bDraging)
{
Super::NativeOnMouseMove(InGeometry, InMouseEvent);
// 获取鼠标在屏幕空间的绝对坐标
FVector2D MouseScreenPos = InMouseEvent.GetScreenSpacePosition();
// 获取Widget在屏幕上的实际渲染尺寸
FVector2D WidgetAbsoluteSize = InGeometry.GetDrawSize();
// 计算Widget中心点应对应的屏幕位置
FVector2D DesiredCenter = MouseScreenPos;
// 计算新的左上角位置(让中心点对准鼠标)
FVector2D NewTopLeft =FVector2D(DesiredCenter.X - WidgetAbsoluteSize.X * 0.5f, DesiredCenter.Y - WidgetAbsoluteSize.Y* 0.5f ); ;
// 边界检查
FVector2D ViewportSize;
if (GEngine && GEngine->GameViewport)
{
GEngine->GameViewport->GetViewportSize(ViewportSize);
}
else
{
ViewportSize = FVector2D(1920, 1080);
}
// 确保Widget不会完全移出屏幕
NewTopLeft.X = FMath::Clamp(NewTopLeft.X, 0.0f, ViewportSize.X - WidgetAbsoluteSize.X);
NewTopLeft.Y = FMath::Clamp(NewTopLeft.Y, 0.0f, ViewportSize.Y - WidgetAbsoluteSize.Y);
// // 计算相对于原始位置的偏移量
// FVector2D ParentAbsolutePosition = FVector2D::ZeroVector;
// if (InGeometry.GetParentGeometry().IsValid())
// {
// ParentAbsolutePosition = InGeometry.GetParentGeometry().GetAbsolutePosition();
// }
//
FVector2D LocalOffset = NewTopLeft - OriginWidgetScreenPos;
// 应用变换
FWidgetTransform WidgetTransform = GetRenderTransform();
WidgetTransform.Translation = LocalOffset/InGeometry.Scale;
SetRenderTransform(WidgetTransform);
// FString Scale = FString::Printf(TEXT("%.0f"), InGeometry.Scale);
// UE_LOG(LogTemp, Warning, TEXT("Mouse: %s, CurrentWidgetScreenPos: %s, WidgetAbsoluteSize: %s NewTopLeft : %s LocalOffset : %s Scale = %s"),
// *MouseScreenPos.ToString(),
// *OriginWidgetScreenPos.ToString(),
// *WidgetAbsoluteSize.ToString(),
// *NewTopLeft.ToString(),
// *LocalOffset.ToString(),
// *Scale
// );
return FReply::Handled();
}
else
return Super::NativeOnMouseMove(InGeometry, InMouseEvent);
}

View File

@ -0,0 +1,37 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "DragableUserWidget.generated.h"
/**
*
*/
UCLASS()
class PROJECTFISH_API UDragableUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "Dragable Widget")
void SetWidgetDragable(bool Dragable);
UFUNCTION(BlueprintCallable, Category = "Dragable Widget")
void BeginDrag(const FGeometry& InGeometry);
UFUNCTION(BlueprintCallable, Category = "Dragable Widget")
void EndDrag();
virtual FReply NativeOnMouseButtonDown( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent ) override;
virtual FReply NativeOnMouseButtonUp( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent ) override;
virtual FReply NativeOnMouseMove( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent ) override;
protected:
UPROPERTY(BlueprintReadWrite, EditAnywhere)
bool bDragable;
UPROPERTY(BlueprintReadOnly)
bool bDraging;
FVector2D OriginWidgetScreenPos;
};