如何在坐标系变换时保持3D物体朝向?Unity至自研引擎迁移问询
解决Unity到自研引擎的3D朝向迁移问题
你的思路用forward和up向量直接构建视图矩阵真的很靠谱——绕开了旋转顺序、坐标系方向转换的各种坑,比硬转欧拉角稳定太多了。下面我一步步拆解细节,帮你把这个方案落地:
第一步:Unity中正确导出方向向量
Unity是左手坐标系(Y向上、Z向前),你要确保导出的是物体世界空间下的方向向量:
- 直接取物体的
transform.forward(世界空间Z轴向前方向) - 直接取物体的
transform.up(世界空间Y轴向上方向) - 把这两个向量的x/y/z分量原封不动存到文件里就行,不用提前做任何转换。
第二步:自研引擎中适配坐标系差异
你的自研引擎是右手坐标系(Y向下、Z向前),这里只需要做一个简单的向量适配:
- 两个引擎的X轴都是向右、Z轴都是向前,所以forward向量的x/z分量不用改
- Unity的Y轴向上,自研的Y轴向下,所以把up向量的Y分量取反:
自研_up.y = -Unity_up.y
第三步:用glm::lookAtLH构建朝向矩阵
这里要注意glm::lookAtLH的参数逻辑:
eye:物体的世界位置,如果只需要朝向矩阵,可以先设为glm::vec3(0,0,0),后续再和位置平移矩阵合并center:eye + forward向量——因为lookAt是从eye看向center,所以直接用eye + 自研_forward即可up:转换后的自研_up向量
给你个代码示例参考:
// 读取Unity导出的向量数据 glm::vec3 unity_forward = glm::vec3(forward_x, forward_y, forward_z); glm::vec3 unity_up = glm::vec3(up_x, up_y, up_z); // 适配自研引擎坐标系 glm::vec3 engine_forward = unity_forward; // X、Z方向一致,无需修改 glm::vec3 engine_up = glm::vec3(unity_up.x, -unity_up.y, unity_up.z); // 翻转Y轴 // 构建朝向矩阵(假设物体世界位置为pos) glm::vec3 eye = pos; glm::vec3 center = eye + engine_forward; glm::mat4 orientation_matrix = glm::lookAtLH(eye, center, engine_up);
额外注意事项
- 如果需要完整的物体世界变换矩阵,把朝向矩阵和位置平移矩阵相乘即可:
world_matrix = glm::translate(glm::mat4(1.0f), pos) * orientation_matrix - 读取向量后建议做一次归一化——Unity导出的向量本来是单位向量,但保存/读取可能有精度损失:
engine_forward = glm::normalize(engine_forward); engine_up = glm::normalize(engine_up); - 如果后续要从矩阵反推欧拉角,记得用自研引擎支持的旋转顺序(比如你提到的XYZ顺时针),glm的
glm::eulerAngles可以实现,但要注意对应好坐标系和旋转方向。
这个方案完全避开了欧拉角的万向锁问题,也不用纠结两种引擎旋转顺序的复杂转换,直接用方向向量构建矩阵,稳定性和精度都有保障。
内容的提问来源于stack exchange,提问作者Tony Forge
相关产品推荐
相关产品推荐

