You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

应用Transform后如何获取Entity真实的朝向/旋转角度值?

RealityKit 获取 Entity 当前旋转角度实现方法

核心原因

entity.orientation返回的是simd_quatf四元数类型,不会直接返回弧度/角度格式的欧拉角数值,你需要手动完成四元数到欧拉角的转换,转换时需要匹配RealityKit默认的旋转顺序:pitch(绕X轴俯仰)→ yaw(绕Y轴偏航)→ roll(绕Z轴翻滚),避免计算结果偏差。

可直接复用的转换代码

给simd_quatf写扩展,直接从四元数取出弧度制的三个欧拉角:

import simd

extension simd_quatf {
    /// 返回弧度制欧拉角,顺序为(pitch: 俯仰X轴, yaw: 偏航Y轴, roll: 翻滚Z轴)
    var eulerAngles: (pitch: Float, yaw: Float, roll: Float) {
        let x = imag.x, y = imag.y, z = imag.z, w = real
        
        // 计算X轴pitch
        let sinPitch = 2 * (w * x + y * z)
        let cosPitch = 1 - 2 * (x * x + y * y)
        let pitch = atan2(sinPitch, cosPitch)
        
        // 计算Y轴yaw,处理万向锁边界
        let sinYaw = 2 * (w * y - z * x)
        let yaw: Float
        if abs(sinYaw) >= 1 {
            yaw = copysign(.pi / 2, sinYaw)
        } else {
            yaw = asin(sinYaw)
        }
        
        // 计算Z轴roll
        let sinRoll = 2 * (w * z + x * y)
        let cosRoll = 1 - 2 * (y * y + z * z)
        let roll = atan2(sinRoll, cosRoll)
        
        return (pitch, yaw, roll)
    }
}

调用方式

替换你原来的打印逻辑即可拿到符合预期的角度值:

entity.setOrientation(transform.rotation, relativeTo: nil)

// 获取当前旋转值
let currentEuler = entity.orientation.eulerAngles
print("pitch 弧度值:\(currentEuler.pitch)") // 输出约1.5708,对应.pi/2
print("pitch 角度值:\(currentEuler.pitch * 180 / .pi)") // 输出约90.0

旋转范围限制实现提示

做交互旋转限制时,按以下逻辑处理即可:

  • 每次识别到用户旋转手势,先计算手势带来的pitch增量
  • 用当前pitch值加上增量得到目标pitch值
  • 用clamp方法把目标pitch限制在-.pi/2 ~ .pi/2(即-90°~90°)区间
  • 用限制后的pitch值生成新的旋转四元数,赋值给实体即可

注意:如果设置旋转时用的是relativeTo: nil(世界坐标系),取orientation得到的也是世界坐标系下的旋转值,参考系一致不会出现计算偏差;如果是相对父实体旋转,要对应使用entity.orientation(relativeTo: 父实体)取值。

内容的提问来源于stack exchange,提问作者ZbadhabitZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:06:22