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

Raylib第一人称射击游戏中如何让武器随相机上下移动时保持在视野内?

解决Raylib第一人称武器随相机俯仰移出视野的问题

问题根源

你当前的代码只处理了相机的偏航(左右旋转),完全忽略了俯仰(上下旋转):

  • 武器位置计算仅基于世界空间的前向/右向向量,没有考虑相机垂直方向的朝向偏移,导致抬头/低头时武器位置没跟着垂直移动。
  • 武器旋转只绕Y轴(偏航),没有应用相机的俯仰角度,武器不会随相机抬头低头,视觉上脱节且容易移出视野。

核心解决方案

武器的位置和旋转必须完全基于相机的局部坐标系计算,而不是世界空间的向量。简单来说:

  1. 定义武器相对于相机的固定局部偏移(比如“在相机前方0.5米、左侧0.2米、下方0.1米”)。
  2. 将这个局部偏移转换为世界空间坐标,跟随相机的旋转变化。
  3. 让武器继承相机的完整旋转(偏航+俯仰),确保视觉同步。

修改后的代码实现

情况1:使用Raylib的CAMERA_FIRST_PERSON模式

如果你的相机是CAMERA_FIRST_PERSON类型,Raylib已经帮你维护了camera.rotation(x=俯仰角,y=偏航角),直接用即可:

// 1. 定义武器在相机局部空间的固定偏移(根据你的模型调整数值)
// 含义:向前0.5m,向下0.1m,向左0.2m(适配多数第一人称武器模型朝向)
Vector3 localWeaponOffset = { 0.5f, -0.1f, -0.2f };

// 2. 计算相机的旋转矩阵(包含偏航和俯仰)
Matrix cameraRotation = MatrixRotateYawPitchRoll(
    camera.rotation.y * DEG2RAD,  // 偏航角转弧度
    camera.rotation.x * DEG2RAD,  // 俯仰角转弧度
    0.0f                          // 滚转角,第一人称一般不需要
);

// 3. 将局部偏移转换为世界空间的偏移
Vector3 worldOffset = Vector3Transform(localWeaponOffset, cameraRotation);

// 4. 计算武器的世界位置:相机位置 + 世界空间偏移
Vector3 weaponPosition = Vector3Add(camera.position, worldOffset);

// 5. 计算武器的旋转:完全继承相机的旋转(可额外加后坐力等效果)
Vector3 weaponRotation = camera.rotation;

// 6. 绘制武器(用矩阵方式更高效,也可以用DrawModelEx分步旋转)
Matrix modelMatrix = MatrixMultiply(
    MatrixTranslate(weaponPosition.x, weaponPosition.y, weaponPosition.z),
    MatrixRotateYawPitchRoll(
        weaponRotation.y * DEG2RAD,
        weaponRotation.x * DEG2RAD,
        0.0f
    )
);
// 注意:DrawModel的位置参数传(0,0,0),因为模型矩阵已经包含了平移
DrawModel(m4Model, (Vector3){0, 0, 0}, 1.0f, WHITE);

情况2:手动控制相机(自定义target/position)

如果是手动维护相机的position和target,需要自己计算俯仰和偏航角:

// 1. 计算相机的前向向量
Vector3 forward = Vector3Normalize(Vector3Subtract(camera.target, camera.position));

// 2. 计算相机的俯仰角(X轴旋转)和偏航角(Y轴旋转)
float pitch = asinf(forward.y);          // 俯仰角,范围 -π/2 ~ π/2
float yaw = atan2f(forward.x, forward.z); // 偏航角,范围 -π ~ π

// 3. 后续步骤和情况1一致:定义局部偏移→计算旋转矩阵→转换世界偏移→计算位置和旋转
Vector3 localWeaponOffset = { 0.5f, -0.1f, -0.2f };
Matrix cameraRotation = MatrixRotateYawPitchRoll(yaw, pitch, 0.0f);
Vector3 worldOffset = Vector3Transform(localWeaponOffset, cameraRotation);
Vector3 weaponPosition = Vector3Add(camera.position, worldOffset);

// 绘制武器
Matrix modelMatrix = MatrixMultiply(
    MatrixTranslate(weaponPosition.x, weaponPosition.y, weaponPosition.z),
    MatrixRotateYawPitchRoll(yaw, pitch, 0.0f)
);
DrawModel(m4Model, (Vector3){0, 0, 0}, 1.0f, WHITE);

关键注意点

  • 局部偏移调整:localWeaponOffset的数值需要根据你的武器模型朝向测试调整,比如模型默认朝Z轴负方向的话,Z值要改成正的。
  • 避免固定Y位置:不要用camera.position.y - 1.0f这种固定世界Y轴的方式,必须通过局部偏移的旋转来处理垂直位置,否则俯仰时武器会脱节。
  • 旋转同步:武器必须同时应用俯仰和偏航旋转,否则只会左右转,视觉上会很违和。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 06:17:07