【UE C++】虚幻引擎防止鼠标单击偏移的方法
前言
在数字孪生项目中涉及到鼠标交互时经常会有一些单击的交互需求,但因尝尝鼠标拖动时涉及到视口的控制,会与点击事件冲突,我们可以通过获取鼠标按下和松开时,两次鼠标在屏幕中的位置来做一些判断来规避这些交互上的冲突。
代码实现
第一步:
定义一个FVector2D属性,用于存鼠标按下时鼠标在视口中的位置。
// 射线发送时鼠标在View中的位置(UV)
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector2D screenPosition;
第二步:
在相应的鼠标交互事件 ,如果想做到左键防偏移,就在左键按下的事件中更新screenPosition位置。
// 本文不涉及怎么在C++找到对应的Input处理事件 办法很多 自行百度
// 此处使用EKeys做例子
if (PlayerController->IsInputKeyDown(EKeys::LeftMouseButton))
{
GetLocalPlayer()->ViewportClient->GetMousePosition(screenPosition);
}
丢一下源码 在UGameViewportClient中已封装。
bool UGameViewportClient::GetMousePosition(FVector2D& MousePosition) const
{
bool bGotMousePosition = false;
if (Viewport && FSlateApplication::Get().IsMouseAttached())
{
FIntPoint MousePos;
Viewport->GetMousePos(MousePos);
if (MousePos.X >= 0 && MousePos.Y >= 0)
{
MousePosition = FVector2D(MousePos);
bGotMousePosition = true;
}
}
return bGotMousePosition;
}
第三步:
在相应的鼠标交互事件 ,如果想做到左键防偏移,就在左键松开的事件中拿screenPosition和新的位置属性作对比
// 计算鼠标右键点下和抬起时两个FVector2D的向量距离,高于某个值视为误触 不进行相应的交互(同时不影响拖动等操作)
FVector2D newScreenPosition;
GetLocalPlayer()->ViewportClient->GetMousePosition(newScreenPosition);
float distance = FVector2D::Distance(screenPosition, newScreenPosition);
// 50Pixel外距离算误触
if ( distance <= 1 * 50)
{
DO YOUR METHOD
}
更方便的封装
建一个结构体,把按下时screenPosition和 松开时newScreenPosition 两个FVector2D的属性,和一个原生FHitResult结构体封入。使用这个新的结构体替代FHitResult使用,这样无论在任何交互(左键右键滚轮) 都可以用这种方式去防止偏移
USTRUCT(BlueprintType)
struct FCustomHitResult
{
GENERATED_USTRUCT_BODY()
public:
FCustomHitResult()
{
}
// UE 原生Hitresult
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FHitResult hitResult;
// 射线发送时鼠标在View中的位置(UV)
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector2D screenPosition;
// 射线发送时鼠标在View中的位置(UV)
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector2D newScreenPosition;
};