如何计算两物体间的Look At Rotation?SLERP目标旋转求解步骤
问题
我希望在一段时间内通过SLERP将ObjectA(蜘蛛)的旋转插值至朝向ObjectB(玩家)的位置。目前插值功能可正常工作,但无法确定如何生成目标旋转(DestinationRotation,即ObjectA最终需要达到的Look to Rotation)。现需了解完成该目标的步骤,我可使用的工具包括:
- 两物体的vector3旋转值;
- 两物体的vector3位置;
- 两物体的vector3轴;
- 每个物体的角度;
- 两物体位置X、Y分量的点积;
- 两向量间的欧氏距离;
- 每个物体的局部向上向量;
- 每个物体的局部向前向量。
注:使用Unreal Engine空间数学库的Verse编程语言,问题并非代码实现,而是需明确使用数学工具的顺序。
附当前代码(旋转部分存在问题):
loop: Sleep(0.0) CurrentTime := GetSimulationElapsedTime() DeltaTime := CurrentTime - PreviousTime set PreviousTime = CurrentTime var MoveToPosition : vector2 = vector2{X := 0.0, Y := 0.0} # Player Current Position if (Agent := agent[Player], FortChar := Agent.GetFortCharacter[], Trans := FortChar.GetTransform(), Position := Trans.Translation): set MoveToPosition = vector2{X := Position.X, Y := Position.Y} SpiderTrans := Spider.GetTransform() SpiderVec := SpiderTrans.Translation CurrentSpiderRotation := SpiderTrans.Rotation CurrentSpiderPos := vector2{X := SpiderVec.X, Y := SpiderVec.Y} DeltaSpeed := SpiderSpeed * DeltaTime NewPos := Lerp(CurrentSpiderPos, MoveToPosition, DeltaSpeed) FinalMoveVector := vector3{X := NewPos.X, Y := NewPos.Y, Z := SpiderVec.Z} # This is where my rotation gets wonky DP := DotProduct(CurrentSpiderPos, MoveToPosition) var NewRotation : rotation = CurrentSpiderRotation.ApplyLocalRotationZ(DP) if (set NewRotation = Slerp[CurrentSpiderRotation,NewRotation, SpiderSpeed]) {} # Movement works fine, but rotation is all over the place if (Spider.TeleportTo[FinalMoveVector, NewRotation]) {}
计算目标朝向旋转的步骤
按以下顺序使用你提供的数学工具生成正确的目标旋转:
计算指向目标的方向向量
- 用两物体的vector3位置:取ObjectA(蜘蛛)和ObjectB(玩家)的X、Y分量,计算从蜘蛛指向玩家的2D方向向量:
TargetDirection = vector2{X: 玩家X坐标 - 蜘蛛X坐标, Y: 玩家Y坐标 - 蜘蛛Y坐标} - 若需要,用两向量间的欧氏距离计算该向量的长度,将其归一化为单位向量(避免后续旋转计算出现缩放问题)。
- 用两物体的vector3位置:取ObjectA(蜘蛛)和ObjectB(玩家)的X、Y分量,计算从蜘蛛指向玩家的2D方向向量:
确定目标前向向量
- 将上一步得到的2D方向向量转换为3D向量(Z分量设为0),作为ObjectA需要朝向的局部向前向量目标。
构建目标旋转
- 结合目标前向向量和ObjectA的局部向上向量(保持Z轴向上即可,因为是平面旋转),使用Unreal/Verse的旋转构造方法(如
MakeRotationFromX或MakeRotationFromAxes)生成最终的DestinationRotation。
- 结合目标前向向量和ObjectA的局部向上向量(保持Z轴向上即可,因为是平面旋转),使用Unreal/Verse的旋转构造方法(如
执行SLERP插值
- 拿ObjectA的当前vector3旋转值和刚生成的
DestinationRotation,以DeltaSpeed为插值因子进行SLERP插值,得到每一帧的过渡旋转。
- 拿ObjectA的当前vector3旋转值和刚生成的
原代码问题说明
你当前用点积直接作为旋转角度的逻辑错误,点积结果是向量投影值而非角度值,这会导致旋转混乱。正确逻辑是先生成指向目标的方向向量,再基于该向量构建目标旋转,最后做SLERP插值。
内容的提问来源于stack exchange,提问作者Wahlbeck Warforge
相关产品推荐
相关产品推荐

