johnsoncodehk 发表于 2022-10-2 11:41

【Unreal】在编辑器的Viewport中显示鼠标在世界中的投射 ...

在关卡Viewport操作的时候,有些时候希望能直观地显示出鼠标投射到关卡Mesh上地位置来辅助操作,尤其是透视结构比较复杂地时候(下面的截图没有鼠标指针,大家意会= =)





鼠标投射的位置在LandscapeEdMode.cpp中就有实现,因为正常的编辑模式也是需要识别你鼠标按下去的时候要选中哪个物体,所以基础功能的大部分肯定是现成的


具体实现最终是在LandScapeTrace这个函数中,比较长就不全部截取了,有兴趣的可以自己去看看


那么我们创造一个蓝图库里面来仿写这个功能,头文件如下
#pragma once
#include "Editor.h"
#include "EditorViewportClient.h"

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"


/**
*
*/
UCLASS()
class TESTPROJECT_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
        GENERATED_BODY()

                UFUNCTION(BlueprintCallable, Category = "TestFunction")
                static bool getMousePositionAtActiveViewport(int32& mouseX, int32& mouseY, float& mouseU, float& mouseV);
                UFUNCTION(BlueprintCallable, Category = "TestFunction")
                static void getMouseTraceLocation(FVector& targetLoc);
};
这里面主要是两个函数,一个用来获取鼠标在活动的视窗下的位置getMousePositionAtActiveViewport,以及这个位置在世界中的投射getMouseTraceLocation(这个返回值直接使用了FVector,也可以直接用Hitresult)
.cpp:
#include "MyBlueprintFunctionLibrary.h"
#include "Editor.h"
#include "EditorViewportClient.h"
#include "EditorModes.h"

bool UMyBlueprintFunctionLibrary::getMousePositionAtActiveViewport(int32 & mouseX, int32 & mouseY, float & mouseU, float & mouseV)
{
        FIntPoint mousePos;
        GEditor->GetActiveViewport()->GetMousePos(mousePos, true);
        mouseX = mousePos.X;
        mouseY = mousePos.Y;
        mouseU = float(mouseX) / float(GEditor->GetActiveViewport()->GetSizeXY().X);
        mouseV = float(mouseY) / float(GEditor->GetActiveViewport()->GetSizeXY().Y);
        return (GEditor->GetActiveViewport()!=NULL);
}

void UMyBlueprintFunctionLibrary::getMouseTraceLocation(FVector & targetLoc)
{
        FEditorViewportClient* ViewportClient = (FEditorViewportClient*)GEditor->GetActiveViewport()->GetClient();
        FIntPoint mousePos;
        GEditor->GetActiveViewport()->GetMousePos(mousePos, true);
        UWorld* World = ViewportClient->GetWorld();
        FSceneViewFamilyContext ViewFamily(FSceneViewFamilyContext::ConstructionValues(ViewportClient->Viewport, ViewportClient->GetScene(), ViewportClient->EngineShowFlags)
                .SetRealtimeUpdate(ViewportClient->IsRealtime()));
        FSceneView* View = ViewportClient->CalcSceneView(&ViewFamily);
        FViewportCursorLocation MouseViewportRay(View, ViewportClient, mousePos.X, mousePos.Y);
        FVector MouseViewportRayDirection = MouseViewportRay.GetDirection();
        FVector Start = MouseViewportRay.GetOrigin();
        FVector End = Start + WORLD_MAX * MouseViewportRayDirection;
        if (ViewportClient->IsOrtho())
        {
                Start -= WORLD_MAX * MouseViewportRayDirection;
        }       
        TArray<FHitResult> Results;
        World->LineTraceMultiByObjectType(Results, Start, End, FCollisionObjectQueryParams(), FCollisionQueryParams(SCENE_QUERY_STAT(EditorViewWatcherWindowTrace), true));
        for (int32 i = 0; i < Results.Num(); i++)
        {
                const FHitResult& Hit = Results;
                targetLoc = Hit.Location;
        }
}(如果需要HitResult,直接返回Results即可)
之后在任意一个EditorUtilityBlueprint建立一个Draw Debug Sphere函数,勾选CallInEditor然后按帧调用即可,也可以在此设置DebugSphere的具体细节
这部分如果有问题可以搜索一下EditorUtilityObject的用法

页: [1]
查看完整版本: 【Unreal】在编辑器的Viewport中显示鼠标在世界中的投射 ...