游戏开发:让沿圆周运动的Plane朝向运动方向
问题分析与解决
你的代码存在几个核心问题,以下是针对性的修正方案:
1. 圆周位置计算错误
当前位置更新逻辑position = vec3(position.x + x, position.y, position.z + y)会让飞机不断偏离初始圆心,导致圆周半径持续变大,完全不符合固定半径的运动要求。正确做法是基于固定圆心计算当前位置:
// 定义圆周圆心,可根据你的游戏需求调整坐标 vec3 center(0.0f, 0.0f, 0.0f); float x = radius * cos(angle); float z = radius * sin(angle); // 统一变量名,避免与Y轴混淆 position = vec3(center.x + x, center.y, center.z + z);
2. 方向与旋转未关联圆周运动
你用yaw和pitch计算方向,但这两个变量未随圆周运动角度更新,自然无法让飞机朝向运动方向。圆周运动的切线方向才是飞机应朝向的方向,对于X-Z平面的圆周(角度angle从X轴正方向逆时针旋转),切线方向向量为(-sin(angle), 0.0f, cos(angle))(与径向垂直,指向运动方向)。
基于切线方向计算旋转矩阵,让飞机朝向该方向:
// 计算切线方向并归一化 vec3 tangentDirection(-sin(angle), 0.0f, cos(angle)); tangentDirection = tangentDirection.unit(); // 计算绕Y轴的旋转角(yaw),将方向转换为角度(适配矩阵旋转函数的参数要求) float targetYaw = atan2(tangentDirection.x, tangentDirection.z) * 180.0f / M_PI;
3. 模型矩阵构建顺序错误
模型矩阵的标准构建顺序为缩放 → 旋转 → 平移(列主序矩阵,如OpenGL环境),且viewMatrix应最后与模型矩阵相乘(你当前的顺序会导致变换错乱)。修正后的矩阵构建:
Matrix model = Matrix::Scale(vec3(scale, scale, scale)) * Matrix::RotateY(targetYaw) * // 绕Y轴旋转,让飞机朝向切线方向 Matrix::Translate(position); // 最终变换矩阵(按引擎要求调整worldMatrix的位置) modelMatrix = viewMatrix * model * worldMatrix;
修正后的完整Update函数
void Update(float deltaTime, const Matrix& worldMatrix, const Matrix& viewMatrix) { vec3 center(0.0f, 0.0f, 0.0f); // 自定义圆心位置 float x = radius * cos(angle); float z = radius * sin(angle); position = vec3(center.x + x, center.y, center.z + z); angle += speed * deltaTime; if (angle > 2 * M_PI) { angle -= 2 * M_PI; } // 计算切线方向与目标旋转角 vec3 tangentDirection(-sin(angle), 0.0f, cos(angle)); tangentDirection = tangentDirection.unit(); float targetYaw = atan2(tangentDirection.x, tangentDirection.z) * 180.0f / M_PI; // 构建正确的模型矩阵 Matrix model = Matrix::Scale(vec3(scale, scale, scale)) * Matrix::RotateY(targetYaw) * Matrix::Translate(position); modelMatrix = viewMatrix * model * worldMatrix; }
为什么之前的atan2尝试失败?
你用auto d = atan2(x, y) * 180 / 3.14;得到的是径向角度(从圆心指向飞机的方向),而非切线方向的角度。切线方向角度需要在径向角度基础上加90°(π/2弧度),直接用-sin(angle)和cos(angle)计算方向则可避免持续旋转的问题。
内容的提问来源于stack exchange,提问作者blov
相关产品推荐
相关产品推荐

