UE4坐标变换运算

本文详细解释了UE4中坐标变换的基本原理,包括不同旋转顺序对结果的影响、FTransform和FQuaternion乘法的区别,以及如何通过变换增量实现从一个坐标系到另一个坐标系的转换。此外,还介绍了父节点与子节点间坐标变换的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

> 旋转顺序很重要。不同旋转顺序,造成的结果可能就不同。

上图中A、B为两个垂直于屏幕的旋转轴,X为物体,首先将X绕A轴逆时针转90°,然后绕B轴逆时针转90°,那么X会回到最开始的地方。

上图中,若将X先绕B轴逆时针转90°,再绕A轴逆时针转90°,那么X最终会运动到X'''处。

> FRotator, FTransform, FMatrix乘法都是先运用左边的变换,再运用右边的变换。FQuaternion乘法是先运用右边的变换,再运用左边的变换。规定以下变换均为FTransform形式表示。

> 如有世界系变换A,再有一个世界系变换B,假设从A变换到B还需要的世界系变换增量为D,则A * D = B。再来一个最重要的例子:父节点世界系变换为P,子节点世界系变换为C,设D为从P运动到C的世界系变换,则P * D = C。设L为子节点在父节点下的局部变换,因为P就是父节点到世界系的坐标变换,因此 L * P = C,其理解就是父节点没有初始变换时,L就是子节点的世界系变换描述,这时父节点进行P变换,会带动子节点进行同样的世界系变换P,此时子节点的世界系变换C = L * P。注意这里的D和L的区别,它俩是不同的坐标系变换描述,D是世界系变换,L是局部系变换。这两个等式的意义和用法是UE4的坐标变换里最最重要的东西,一定要搞清楚。

还有一种应用,是逻辑上将子节点看做是父节点,变换子节点时,父节点随子节点做相同变换,这种情况下,父节点与子节点的相对关系是不变的,即上面说的L是固定的。

转载于:https://my.oschina.net/zhoubaojing/blog/1628987

<think>嗯,用户想知道UE4里怎么把屏幕坐标转成世界坐标。我需要先回忆一下UE4的相关API和流程。首先,屏幕坐标通常是鼠标的位置或者UI元素的二维坐标,而转换成世界坐标可能需要用到摄像头的投影和视图矩阵。 首先,我应该想到UE4的PlayerController。因为玩家控制器可以获取到视口的信息,包括鼠标的位置。然后可能需要用到Deproject Screen to World这个函数。这个函数的作用应该是将屏幕坐标转换为世界空间中的射线,也就是起点和方向。 接下来,步骤应该是这样的:先获取玩家的视口,然后用Deproject Screen to World将屏幕坐标转换为世界空间中的射线。之后可能需要做射线检测,比如LineTraceSingleByChannel,来找到碰撞点,这样就能得到准确的世界坐标位置。 不过,用户可能只是想得到一个方向或者射线,而不仅仅是碰撞点。所以需要分两种情况:一种是只需要转换后的射线起点和方向,另一种是需要实际的碰撞点坐标。可能都需要在回答中提到。 另外,应该注意是否需要考虑摄像头的投影方式,比如透视和正投影的区别。但UE4的Deproject函数应该已经处理了这些细节。此外,蓝图中和C++的实现可能有不同的方法,用户可能需要两方面的信息,但问题中没有明确说明,所以最好都简要提及。 还有,用户可能是在做点击选择物体或者生成物体到屏幕点击的位置,所以示例代码或步骤需要具体。比如在蓝图中,如何通过鼠标事件获取屏幕坐标,然后转换,再用射线检测得到世界坐标。 最后,确保语法正确,使用中文,结构清晰,分步骤说明,可能还要提醒常见错误,比如视口大小是否正确获取,或者射线检测的碰撞通道是否设置正确。</think>在UE4中将屏幕坐标转换为世界坐标需要结合摄像头信息和几何计算,以下是详细步骤分解: ### 核心方法:使用Deproject Screen To World ```cpp // C++实现核心代码 APlayerController* PC = GetWorld()->GetFirstPlayerController(); FVector WorldLocation, WorldDirection; PC->DeprojectScreenPositionToWorld( ScreenPos.X, ScreenPos.Y, WorldLocation, WorldDirection ); ``` ### 分步实现流程 1. **获取玩家控制器** ```cpp APlayerController* PC = GetWorld()->GetFirstPlayerController(); ``` 这是操作的核心入口,用于访问视口信息 2. **执行坐标反投影** ```cpp FVector2D ScreenPosition = FVector2D(1920/2, 1080/2); // 屏幕中心坐标 FVector WorldOrigin, WorldDirection; bool bSuccess = PC->DeprojectScreenPositionToWorld( ScreenPosition.X, ScreenPosition.Y, WorldOrigin, WorldDirection ); ``` 得到的WorldOrigin是摄像头位置,WorldDirection是射线方向 3. **射线检测获取实际坐标** ```cpp FHitResult HitResult; FCollisionQueryParams Params; FVector Start = WorldOrigin; FVector End = Start + WorldDirection * 10000; // 设置合理检测距离 if(GetWorld()->LineTraceSingleByChannel( HitResult, Start, End, ECC_Visibility, Params)) { FVector WorldLocation = HitResult.Location; // 最终世界坐标 } ``` 通过射线检测确定与场景物体的交点 ### 蓝图实现方案 1. 右键点击事件获取屏幕坐标 2. 连接"Deproject Screen To World"节点 3. 使用"Line Trace by Channel"节点执行检测 4. 从HitResult中提取Location数据 ### 关键注意事项 1. **坐标系差异**:UE4使用左手坐标系,Y轴向前,Z轴向上 2. **视口比例**:需确保获取的是正确的视口分辨率 3. **碰撞设置**:被检测物体需要开启Visibility碰撞通道 4. **摄像头状态**:正交投影模式下的转换需要特殊处理 ### 数学原理 转换过程基于投影矩阵的逆向运算: $$ \begin{pmatrix} x_{clip} \\ y_{clip} \\ z_{clip} \\ w_{clip} \end{pmatrix} = M_{projection} \cdot M_{view} \cdot \begin{pmatrix} x_{world} \\ y_{world} \\ z_{world} \\ 1 \end{pmatrix} $$ 通过逆向计算获取世界坐标,其中$M_{projection}$和$M_{view}$分别是投影和视图矩阵。 建议在实际使用中结合具体需求选择直接使用反投影结果或进行射线检测,后者更适合需要物体交互的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值