網(wǎng)站空間商推薦怎么發(fā)外鏈
UE4/UE5 基于2D屏幕坐標(biāo)獲取場景3D坐標(biāo)
- 一、射線檢測
- 1)定義
- 1)射線與3D場景中的物體交互的流程
- 2)射線檢測藍(lán)圖函數(shù)
- 3)藍(lán)圖實(shí)現(xiàn)根據(jù)鼠標(biāo)點(diǎn)擊位置獲取場景中的坐標(biāo)值
- 4)根據(jù)相機(jī)中心點(diǎn)獲取場景中的坐標(biāo)值
- 5)射線檢測相關(guān)C++函數(shù)
- 6)C++實(shí)現(xiàn)手動(dòng)創(chuàng)建射線檢測
- 7)C++實(shí)現(xiàn)點(diǎn)擊獲取場景中的坐標(biāo)值
- 二、非射線檢測的情況
- 1)根據(jù)相機(jī)當(dāng)前位置獲取中心點(diǎn)的世界坐標(biāo)
一、射線檢測
1)定義
射線檢測(Ray Casting) 是一種計(jì)算機(jī)圖形和計(jì)算機(jī)圖形學(xué)中的基本技術(shù),用于檢測光線或射線是否與三維場景中的物體相交,以確定相交點(diǎn)的位置和其他相關(guān)信息。射線檢測通常用于實(shí)現(xiàn)各種交互功能、渲染效果和物理模擬,包括但不限于鼠標(biāo)拾取、光線追蹤、碰撞檢測和物體拾取等。
1)射線與3D場景中的物體交互的流程
步驟 | 描述 |
---|---|
1 | 定義射線: 定義射線的起點(diǎn)和方向向量。 |
2 | 檢測相交: 沿著射線的方向,從起點(diǎn)開始沿射線前進(jìn),檢測射線是否與場景中的任何物體相交。 通常,這涉及到進(jìn)行碰撞檢測,以確定是否有物體與射線相交。 |
3 | 確定交點(diǎn): 如果射線與物體相交,計(jì)算交點(diǎn)的位置。 交點(diǎn)通常以3D坐標(biāo)的形式給出,表示射線與物體相交的點(diǎn)。 |
4 | 處理交互: 根據(jù)應(yīng)用的需求,您可以在交互點(diǎn)上執(zhí)行特定的操作,如選擇物體、執(zhí)行動(dòng)作或渲染效果。 |
5 | 遍歷所有可能的相交點(diǎn): 射線檢測通常可以返回多個(gè)相交點(diǎn),因此可以考慮遍歷所有可能的交點(diǎn)以處理多重相交。 |
2)射線檢測藍(lán)圖函數(shù)
藍(lán)圖函數(shù) | 描述 |
---|---|
LineTraceByChannel | 執(zhí)行一條射線檢測,檢測與指定碰撞通道相交的物體。返回一個(gè) Hit Result 結(jié)構(gòu)。 |
SphereTraceByChannel | 以球體的形狀執(zhí)行射線檢測,檢測球體與物體的碰撞。返回一個(gè) Hit Result 結(jié)構(gòu)。 |
LineTraceMultiByChannel | 執(zhí)行射線檢測,檢測與指定碰撞通道相交的所有物體。返回一個(gè) Hit Results 數(shù)組。 |
SphereTraceMultiByChannel | 以球體的形狀執(zhí)行射線檢測,檢測球體與多個(gè)物體的碰撞。返回一個(gè) Hit Results 數(shù)組。 |
BoxTraceByChannel | 執(zhí)行射線檢測,檢測與指定碰撞通道相交的物體,使用盒子形狀。返回一個(gè) Hit Result 結(jié)構(gòu)。 |
MultiSphereTraceByChannel | 執(zhí)行多個(gè)球體形狀的射線檢測,檢測多個(gè)球體與物體的碰撞。返回一個(gè) Hit Results 數(shù)組。 |
LineTraceForObjects | 執(zhí)行射線檢測,檢測與指定物體類型相交的物體。返回一個(gè) Hit Result 結(jié)構(gòu)。 |
SphereTraceForObjects | 以球體的形狀執(zhí)行射線檢測,檢測與指定物體類型相交的物體。返回一個(gè) Hit Result 結(jié)構(gòu)。 |
BoxTraceForObjects | 執(zhí)行射線檢測,檢測與指定物體類型相交的物體,使用盒子形狀。返回一個(gè) Hit Result 結(jié)構(gòu)。 |
MultiSphereTraceForObjects | 執(zhí)行多個(gè)球體形狀的射線檢測,檢測與指定物體類型相交的物體。返回一個(gè) Hit Results 數(shù)組。 |
CapsuleTraceByChannel | 以膠囊體的形狀執(zhí)行射線檢測,檢測膠囊體與物體的碰撞。返回一個(gè) Hit Result 結(jié)構(gòu)。 |
CapsuleTraceForObjects | 以膠囊體的形狀執(zhí)行射線檢測,檢測與指定物體類型相交的物體。返回一個(gè) Hit Result 結(jié)構(gòu)。 |
3)藍(lán)圖實(shí)現(xiàn)根據(jù)鼠標(biāo)點(diǎn)擊位置獲取場景中的坐標(biāo)值
4)根據(jù)相機(jī)中心點(diǎn)獲取場景中的坐標(biāo)值
需要獲取到pawn里的相機(jī)。
5)射線檢測相關(guān)C++函數(shù)
(僅列舉linetrace系列其他大同小異)
LineTraceSingleByChannel
:- 用于檢測一條射線與第一個(gè)相交物體的碰撞。
- 返回一個(gè)
FHitResult
結(jié)構(gòu),其中包含有關(guān)碰撞的信息,如碰撞點(diǎn)、碰撞法線和碰撞物體的引用。
bool UWorld::LineTraceSingleByChannel(FHitResult& OutHit, const FVector Start, const FVector End, ECollisionChannel TraceChannel, const FCollisionQueryParams& Params)
LineTraceMultiByChannel
:- 用于檢測一條射線與多個(gè)相交物體的碰撞。
- 返回一個(gè)
TArray<FHitResult>
,其中包含所有相交物體的碰撞信息。
int32 UWorld::LineTraceMultiByChannel(TArray<FHitResult>& OutHits, const FVector Start, const FVector End, ECollisionChannel TraceChannel, const FCollisionQueryParams& Params)
LineTraceSingleByObjectType
:- 類似于
LineTraceSingleByChannel
,但是使用物體類型(EObjectTypeQuery
)而不是碰撞通道進(jìn)行檢測。
- 類似于
bool UWorld::LineTraceSingleByObjectType(FHitResult& OutHit, const FVector Start, const FVector End, FObjectQueryParams ObjectQueryParams, const FCollisionQueryParams& Params)
LineTraceMultiByObjectType
:- 類似于
LineTraceMultiByChannel
,但是使用物體類型(EObjectTypeQuery
)而不是碰撞通道進(jìn)行檢測。
- 類似于
int32 UWorld::LineTraceMultiByObjectType(TArray<FHitResult>& OutHits, const FVector Start, const FVector End, FObjectQueryParams ObjectQueryParams, const FCollisionQueryParams& Params)
6)C++實(shí)現(xiàn)手動(dòng)創(chuàng)建射線檢測
FVector StartLocation; // 射線的起點(diǎn)坐標(biāo)
FVector ForwardVector; // 射線的方向向量
FHitResult HitResult; // 用于存儲(chǔ)碰撞信息的變量// 設(shè)置射線的起點(diǎn)坐標(biāo)
StartLocation = PlayerCameraComponent->GetComponentLocation(); // PlayerCameraComponent是攝像機(jī)組件// 設(shè)置射線的方向向量
ForwardVector = PlayerCameraComponent->GetForwardVector(); // 獲取攝像機(jī)的前向向量// 建立射線
FVector EndLocation = ((ForwardVector * RayLength) + StartLocation); // 計(jì)算射線的終點(diǎn)坐標(biāo)// 進(jìn)行射線檢測
if (GetWorld()->LineTraceSingleByChannel(HitResult, StartLocation, EndLocation, ECC_Visibility))
{// 射線與物體相交,可以在HitResult中獲取碰撞信息AActor* HitActor = HitResult.GetActor();FVector ImpactPoint = HitResult.ImpactPoint;// 進(jìn)一步處理交互邏輯
}
PlayerCameraComponent:攝像機(jī)組件
LineTraceSingleByChannel:射線檢測函數(shù)
HitResult:碰撞的物體和碰撞點(diǎn)
RayLength:射線的長度;
ECC_Visibility:射線檢測所使用的碰撞通道
7)C++實(shí)現(xiàn)點(diǎn)擊獲取場景中的坐標(biāo)值
void AYourPlayerController::GetSceneLocationFromMouse()
{// 獲取玩家控制器APlayerController* PlayerController = this;if (PlayerController){// 獲取鼠標(biāo)點(diǎn)擊位置FVector MouseLocation, MouseDirection;PlayerController->DeprojectMousePositionToWorld(MouseLocation, MouseDirection);// 創(chuàng)建射線,用于射線檢測FHitResult HitResult;FCollisionQueryParams CollisionParams;// 執(zhí)行射線檢測if (GetWorld()->LineTraceSingleByChannel(HitResult, MouseLocation, MouseLocation + MouseDirection * YourRayLength, ECC_Visibility, CollisionParams)){// 獲取射線與場景相交的位置FVector SceneLocation = HitResult.Location;// 打印結(jié)果UE_LOG(LogTemp, Warning, TEXT("Scene Location: %s"), *SceneLocation.ToString());}}
}
二、非射線檢測的情況
1)根據(jù)相機(jī)當(dāng)前位置獲取中心點(diǎn)的世界坐標(biāo)
void AYourPlayerController::GetCameraCenterLocation()
{// 獲取玩家控制器的視圖控制器APlayerController* PlayerController = this;if (PlayerController){// 獲取相機(jī)組件UCameraComponent* CameraComponent = PlayerController->PlayerCameraManager->GetCameraComponent();if (CameraComponent){// 獲取相機(jī)位置FVector CameraLocation = CameraComponent->GetComponentLocation();// 獲取相機(jī)旋轉(zhuǎn)FRotator CameraRotation = CameraComponent->GetComponentRotation();// 計(jì)算相機(jī)中心點(diǎn)的位置(通常位于相機(jī)位置的前方,視角方向)FVector CameraForwardVector = CameraRotation.Vector();FVector CameraCenterLocation = CameraLocation + CameraForwardVector * YourDistance; // 替換 YourDistance 為相機(jī)中心點(diǎn)到相機(jī)位置的距離// 將相機(jī)中心點(diǎn)的位置轉(zhuǎn)換為場景中的坐標(biāo)FVector WorldLocation = CameraCenterLocation;// 打印結(jié)果UE_LOG(LogTemp, Warning, TEXT("Camera Center Location: %s"), *WorldLocation.ToString());}}
}