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

Raylib模型非原点绘制时网格碰撞检测失效及屏幕中心射线偏差问题求助

Raylib模型非原点绘制时网格碰撞检测失效及屏幕中心射线偏差问题求助

各位Raylib开发者们好!我最近在开发一款第一人称视角的游戏,遇到了两个让我卡壳的问题,折腾了好几天都没找到解决办法,来这儿求助大家!

问题1:模型非原点绘制时碰撞检测完全失效

我需要检测玩家相机射线和模型的碰撞,但发现只有当DrawModel()的位置参数设为世界原点{0, 0, 0}时,才能检测到碰撞;一旦把模型放到其他位置(比如我代码里的{3.0f, 0.5f, 3.0f}),就完全检测不到碰撞了。我猜可能和模型矩阵的变换有关,但不知道具体该怎么处理这个矩阵来让碰撞检测生效。

问题2:屏幕中心射线与十字线不匹配

我在屏幕中心画了十字线用来瞄准,但GetScreenToWorldRay()返回的射线明显不在十字线位置,导致碰撞检测的结果和视觉上的瞄准点对不上,这让我完全搞不懂射线到底是从哪儿发射的。

下面是我的最小复现代码,基本是照着Raylib的mesh picking例子改的,但就是有问题:

#include "raylib.h"
#include "raymath.h"
#include <string>
#include <cmath>
#include <cstring>

int main(void){
    const int screenWidth = 1920;
    const int screenHeight = 1080;

    InitWindow(screenWidth, screenHeight, "Bob's Mansion");
    InitAudioDevice();

    Camera camera = { 0 };
    camera.position = (Vector3){ 0.0f, 1.0f, 5.0f };
    camera.target = (Vector3){ 3.0f, 1.0f, 3.0f };
    camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
    camera.fovy = 60.0f;
    camera.projection = CAMERA_PERSPECTIVE;

    Model BobModel = LoadModel("../assets/BobModel.glb");
    Vector3 BobPosition = { 3.0f, 0.5f, 3.0f };
    // Vector3 BobPosition = { 0.0f, 0.0f, 0.0f }; 只有注释打开时才能检测到碰撞

    Ray ray = { 0 };

    DisableCursor();
    SetTargetFPS(30);

    while(!WindowShouldClose()){
        UpdateCamera(&camera, CAMERA_FIRST_PERSON);
        ray = GetScreenToWorldRay(GetMousePosition(), camera);

        RayCollision collision = { 0 };
        RayCollision meshHitInfo = { 0 };

        for (int m = 0; m < BobModel.meshCount; m++) {
            meshHitInfo = GetRayCollisionMesh(ray, BobModel.meshes[m], BobModel.transform);
            if (meshHitInfo.hit) {
                // 保存最近的碰撞结果
                if ((!collision.hit) || (collision.distance > meshHitInfo.distance))
                    collision = meshHitInfo;
                break; // 检测到一个网格碰撞就停止
            }
        }

        BeginDrawing();
            ClearBackground(BLACK);

            BeginMode3D(camera);
                DrawModel(BobModel, BobPosition, 1.0f, WHITE);
                DrawPlane( {0, 0, 0}, {20, 20}, GRAY);

                // 如果检测到碰撞,绘制碰撞点和法线
                if (collision.hit) {
                    DrawCube(collision.point, 0.3f, 0.3f, 0.3f, GREEN);
                    DrawCubeWires(collision.point, 0.3f, 0.3f, 0.3f, RED);

                    Vector3 normalEnd;
                    normalEnd.x = collision.point.x + collision.normal.x;
                    normalEnd.y = collision.point.y + collision.normal.y;
                    normalEnd.z = collision.point.z + collision.normal.z;
                    DrawLine3D(collision.point, normalEnd, RED);
                }

                DrawRay(ray, MAROON);
            EndMode3D();

            // 绘制屏幕中心十字线
            const float crosshairRadiusOutter = 7;
            const float crosshairRadiusInner = 4;
            DrawCircle(screenWidth/2, screenHeight/2, crosshairRadiusOutter, BLACK);
            DrawCircle(screenWidth/2, screenHeight/2, crosshairRadiusInner, RAYWHITE);
        EndDrawing();
    }

    UnloadModel(BobModel);
    CloseWindow();
}

我已经对照Raylib官方的Mesh Picking例子检查过代码了,还是没搞明白问题出在哪儿。有没有大佬能指点一下,这两个问题该怎么解决呀?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:59:33