UE4/UE5 基于2D屏幕坐标获取场景3D坐标

一、射线检测1)定义1)射线与3D场景中的物体交互的流程2)射线检测蓝图函数3)蓝图实现根据鼠标点击位置获取场景中的坐标值4)根据相机中心点获取场景中的坐标值5)射线检测相关C++函数6)C++实现手动创建射线检测7)C++实现点击获取场景中的坐标值

二、非射线检测的情况1)根据相机当前位置获取中心点的世界坐标

一、射线检测

1)定义

射线检测(Ray Casting) 是一种计算机图形和计算机图形学中的基本技术,用于检测光线或射线是否与三维场景中的物体相交,以确定相交点的位置和其他相关信息。射线检测通常用于实现各种交互功能、渲染效果和物理模拟,包括但不限于鼠标拾取、光线追踪、碰撞检测和物体拾取等。

1)射线与3D场景中的物体交互的流程

步骤描述1定义射线:定义射线的起点和方向向量。2检测相交:沿着射线的方向,从起点开始沿射线前进,检测射线是否与场景中的任何物体相交。通常,这涉及到进行碰撞检测,以确定是否有物体与射线相交。3确定交点:如果射线与物体相交,计算交点的位置。交点通常以3D坐标的形式给出,表示射线与物体相交的点。4处理交互:根据应用的需求,您可以在交互点上执行特定的操作,如选择物体、执行动作或渲染效果。5遍历所有可能的相交点:射线检测通常可以返回多个相交点,因此可以考虑遍历所有可能的交点以处理多重相交。

2)射线检测蓝图函数

蓝图函数描述LineTraceByChannel执行一条射线检测,检测与指定碰撞通道相交的物体。返回一个 Hit Result 结构。SphereTraceByChannel以球体的形状执行射线检测,检测球体与物体的碰撞。返回一个 Hit Result 结构。LineTraceMultiByChannel执行射线检测,检测与指定碰撞通道相交的所有物体。返回一个 Hit Results 数组。SphereTraceMultiByChannel以球体的形状执行射线检测,检测球体与多个物体的碰撞。返回一个 Hit Results 数组。BoxTraceByChannel执行射线检测,检测与指定碰撞通道相交的物体,使用盒子形状。返回一个 Hit Result 结构。MultiSphereTraceByChannel执行多个球体形状的射线检测,检测多个球体与物体的碰撞。返回一个 Hit Results 数组。LineTraceForObjects执行射线检测,检测与指定物体类型相交的物体。返回一个 Hit Result 结构。SphereTraceForObjects以球体的形状执行射线检测,检测与指定物体类型相交的物体。返回一个 Hit Result 结构。BoxTraceForObjects执行射线检测,检测与指定物体类型相交的物体,使用盒子形状。返回一个 Hit Result 结构。MultiSphereTraceForObjects执行多个球体形状的射线检测,检测与指定物体类型相交的物体。返回一个 Hit Results 数组。CapsuleTraceByChannel以胶囊体的形状执行射线检测,检测胶囊体与物体的碰撞。返回一个 Hit Result 结构。CapsuleTraceForObjects以胶囊体的形状执行射线检测,检测与指定物体类型相交的物体。返回一个 Hit Result 结构。

3)蓝图实现根据鼠标点击位置获取场景中的坐标值

4)根据相机中心点获取场景中的坐标值

需要获取到pawn里的相机。

5)射线检测相关C++函数

(仅列举linetrace系列其他大同小异)

LineTraceSingleByChannel:

用于检测一条射线与第一个相交物体的碰撞。返回一个FHitResult结构,其中包含有关碰撞的信息,如碰撞点、碰撞法线和碰撞物体的引用。

bool UWorld::LineTraceSingleByChannel(FHitResult& OutHit, const FVector Start, const FVector End, ECollisionChannel TraceChannel, const FCollisionQueryParams& Params)

LineTraceMultiByChannel:

用于检测一条射线与多个相交物体的碰撞。返回一个TArray,其中包含所有相交物体的碰撞信息。

int32 UWorld::LineTraceMultiByChannel(TArray& OutHits, const FVector Start, const FVector End, ECollisionChannel TraceChannel, const FCollisionQueryParams& Params)

LineTraceSingleByObjectType:

类似于LineTraceSingleByChannel,但是使用物体类型(EObjectTypeQuery)而不是碰撞通道进行检测。

bool UWorld::LineTraceSingleByObjectType(FHitResult& OutHit, const FVector Start, const FVector End, FObjectQueryParams ObjectQueryParams, const FCollisionQueryParams& Params)

LineTraceMultiByObjectType:

类似于LineTraceMultiByChannel,但是使用物体类型(EObjectTypeQuery)而不是碰撞通道进行检测。

int32 UWorld::LineTraceMultiByObjectType(TArray& OutHits, const FVector Start, const FVector End, FObjectQueryParams ObjectQueryParams, const FCollisionQueryParams& Params)

6)C++实现手动创建射线检测

FVector StartLocation; // 射线的起点坐标

FVector ForwardVector; // 射线的方向向量

FHitResult HitResult; // 用于存储碰撞信息的变量

// 设置射线的起点坐标

StartLocation = PlayerCameraComponent->GetComponentLocation(); // PlayerCameraComponent是摄像机组件

// 设置射线的方向向量

ForwardVector = PlayerCameraComponent->GetForwardVector(); // 获取摄像机的前向向量

// 建立射线

FVector EndLocation = ((ForwardVector * RayLength) + StartLocation); // 计算射线的终点坐标

// 进行射线检测

if (GetWorld()->LineTraceSingleByChannel(HitResult, StartLocation, EndLocation, ECC_Visibility))

{

// 射线与物体相交,可以在HitResult中获取碰撞信息

AActor* HitActor = HitResult.GetActor();

FVector ImpactPoint = HitResult.ImpactPoint;

// 进一步处理交互逻辑

}

PlayerCameraComponent:摄像机组件 LineTraceSingleByChannel:射线检测函数 HitResult:碰撞的物体和碰撞点 RayLength:射线的长度; ECC_Visibility:射线检测所使用的碰撞通道

7)C++实现点击获取场景中的坐标值

void AYourPlayerController::GetSceneLocationFromMouse()

{

// 获取玩家控制器

APlayerController* PlayerController = this;

if (PlayerController)

{

// 获取鼠标点击位置

FVector MouseLocation, MouseDirection;

PlayerController->DeprojectMousePositionToWorld(MouseLocation, MouseDirection);

// 创建射线,用于射线检测

FHitResult HitResult;

FCollisionQueryParams CollisionParams;

// 执行射线检测

if (GetWorld()->LineTraceSingleByChannel(HitResult, MouseLocation, MouseLocation + MouseDirection * YourRayLength, ECC_Visibility, CollisionParams))

{

// 获取射线与场景相交的位置

FVector SceneLocation = HitResult.Location;

// 打印结果

UE_LOG(LogTemp, Warning, TEXT("Scene Location: %s"), *SceneLocation.ToString());

}

}

}

二、非射线检测的情况

1)根据相机当前位置获取中心点的世界坐标

void AYourPlayerController::GetCameraCenterLocation()

{

// 获取玩家控制器的视图控制器

APlayerController* PlayerController = this;

if (PlayerController)

{

// 获取相机组件

UCameraComponent* CameraComponent = PlayerController->PlayerCameraManager->GetCameraComponent();

if (CameraComponent)

{

// 获取相机位置

FVector CameraLocation = CameraComponent->GetComponentLocation();

// 获取相机旋转

FRotator CameraRotation = CameraComponent->GetComponentRotation();

// 计算相机中心点的位置(通常位于相机位置的前方,视角方向)

FVector CameraForwardVector = CameraRotation.Vector();

FVector CameraCenterLocation = CameraLocation + CameraForwardVector * YourDistance; // 替换 YourDistance 为相机中心点到相机位置的距离

// 将相机中心点的位置转换为场景中的坐标

FVector WorldLocation = CameraCenterLocation;

// 打印结果

UE_LOG(LogTemp, Warning, TEXT("Camera Center Location: %s"), *WorldLocation.ToString());

}

}

}

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: