找回密码
 立即注册
查看: 321|回复: 0

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

[复制链接]
发表于 2022-10-2 11:41 | 显示全部楼层 |阅读模式
在关卡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的用法

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-18 07:17 , Processed in 0.097598 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表