当前位置: 首页 > 知识库问答 >
问题:

使用THREE。Raycaster检测碰撞

柳杰
2023-03-14

我创建了这个函数,它在渲染循环中调用,以检测碰撞并移动玩家/相机(这是第一人称游戏)。碰撞是使用名为pCube的CubeGeometry检测的,它被移动以匹配每帧的相机:

// Player movements
function pMovements() {
    mPlayer.colBottom = false;

    pCube.position.x = mPlayer.yawObject.position.x + 50; // The cube is placed +50 so we can see/debug it.
    pCube.position.y = mPlayer.yawObject.position.y - 10;
    pCube.position.z = mPlayer.yawObject.position.z;

    // -- COLLISION DETECTION START --
    var originPoint = pCube.position.clone();

    for (var vertexIndex = 0; vertexIndex < pCube.geometry.vertices.length; vertexIndex++)
    {       
        var localVertex = pCube.geometry.vertices[vertexIndex].clone();
        var globalVertex = localVertex.applyMatrix4( pCube.html" target="_blank">matrix );
        var directionVector = globalVertex.sub( pCube.position );

        var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
        var collisionResults = ray.intersectObjects( collidableMeshList );
        if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ) {

            // Bottom vertices
            if (vertexIndex == 2 || vertexIndex == 3 || vertexIndex == 6 || vertexIndex == 7) {
                mPlayer.colBottom = true;
                mPlayer.velocity.y = Math.max( 0, mPlayer.velocity.y ); // Stop falling
            }
        }
    }
    // -- COLLISION DETECTION END --

    var delta = (Date.now() - time) * 0.1;

    mPlayer.velocity.x += (-mPlayer.velocity.x) * 0.08 * delta; // walking
    mPlayer.velocity.z += (-mPlayer.velocity.z) * 0.08 * delta; // walking
    if (mPlayer.colBottom == false) {
        mPlayer.velocity.y -= 0.1 * delta; // falling
    }

    if (mPlayer.moveForward) mPlayer.velocity.z -= mPlayer.speed * delta;
    if (mPlayer.moveBack) mPlayer.velocity.z += mPlayer.speed * delta;
    if (mPlayer.moveLeft) mPlayer.velocity.x -= mPlayer.speed * delta;
    if (mPlayer.moveRight) mPlayer.velocity.x += mPlayer.speed * delta;

    mPlayer.yawObject.translateX(mPlayer.velocity.x);
    mPlayer.yawObject.translateY(mPlayer.velocity.y); 
    mPlayer.yawObject.translateZ(mPlayer.velocity.z);

    if (mPlayer.yawObject.position.y < -2000) {
        // Player has fallen out of bounds :( so re-initialise the players position
        mPlayer.velocity.y = 0;
        mPlayer.yawObject.position.y = 100;
        mPlayer.yawObject.position.x = 0;
        mPlayer.yawObject.position.z = 0;

        mPlayer.yawObject.rotation.y = 0;
        mPlayer.pitchObject.rotation.x = 0;
    }

    if (mPlayer.moveDown) {
        mPlayer.yawObject.position.y -= 1;
    }
    if (mPlayer.moveUp) {
        mPlayer.yawObject.position.y += 1;
    }
}

单击此处观看演示
WASD移动。跳跃空间(排序)。黑色立方体/矩形镜像x轴上的相机位置50。在立方体上检测到冲突。

基本上我对此有两个问题。我应该使用立方体的顶点来检测碰撞,还是使用面来检测?如果对象小于立方体,则不会检测到碰撞,因为它不会击中任何顶点。那么我应该为面部重写它吗?

其次,当检测到碰撞时,如何防止立方体落得太远。如果您查看演示,每当立方体脱落时,它就会继续下降一段时间,然后停止。我假设与mPlayer.velocity.y有关,但我无法修复它。即使跳跃也会使立方体沉入地板深处。

共有1个答案

杨赞
2023-03-14

要提高碰撞检测的“分辨率”,您可以向立方体添加更多顶点,例如,当您声明pCube时,请尝试:

pCube = new THREE.CubeGeometry(100,100,100, 5,5,5);

其余代码可以保持不变。

对于较小的物体在为碰撞检测而创建的光线之间“滑动”,通常如果您使用此方法但让小物体创建光线,那么您将更准确地检测碰撞。

 类似资料:
  • 碰撞检测 现在你知道了如何制造种类繁多的图形对象,但是你能用他们做什么?一个有趣的事情是利用它制作一个简单的 碰撞检测系统 。你可以用一个叫做:hitTestRectangle 的自定义的函数来检测两个矩形精灵是否接触。 hitTestRectangle(spriteOne, spriteTwo) 如果它们重叠, hitTestRectangle 会返回 true。你可以用 hitTestRect

  • 本节暂未进行完全的重写,错误可能会很多。如果可能的话,请对照原文进行阅读。如果有报告本节的错误,将会延迟至重写之后进行处理。 当试图判断两个物体之间是否有碰撞发生时,我们通常不使用物体本身的数据,因为这些物体常常会很复杂,这将导致碰撞检测变得很复杂。正因这一点,使用重叠在物体上的更简单的外形(通常有较简单明确的数学定义)来进行碰撞检测成为常用的方法。我们基于这些简单的外形来检测碰撞,这样代码会变得

  • 我是cocos2d-x的新手,我正在xcode中使用cocos2d-x开发一个游戏。在我的游戏中,我增加了玩家精灵和障碍精灵。障碍精灵不断从右向左移动。现在我正在尝试添加两个精灵之间的碰撞。所以我使用了包围盒。以下是我的代码。但它不起作用。这是我第一次使用边框。 我在init()函数中创建了sprite,并在init函数中声明了上述代码。请帮我解决这个问题。

  • 所以我明白,我现在没有用最好的方式来编写这个代码;这是一种测试运行。我正在尝试使用矩形和intersects属性进行墙碰撞(抱歉,如果我没有使用正确的术语)。到目前为止,我有2个矩形在屏幕上。1玩家控制和游戏中与之冲突的其他玩家。当它们碰撞时,玩家停止移动。问题是,如果玩家试图移动到矩形,而他们已经碰撞,那么玩家不能在垂直于移动的任何方向移动,即如果玩家拿着右箭头键移动到矩形,那么他们不能向上或向

  • 问题内容: 有人可以帮我了解JS中冲突检测的工作原理吗?我不能使用jQuery或gameQuery-已经使用了原型- 因此,我正在寻找非常简单的东西。不要求完整的解决方案,只需为我指明正确的方向。 假设有: 现在球正在移动(任何方向)。“ Someobject”(0-X)已经预先定义,其中有20-60个随机放置,如下所示: 我可以创建一个位置为“ someobject(X)”的数组,并在“球”移动

  • 我已经尝试添加冲突检测一段时间了,但似乎做不到... 要绘制地图,我只需使用x,y坐标: 使用这种方法,我想出了这种检测: 我一直在尝试使用for循环遍历树来检测玩家(一个矩形)是否穿过树,但我想不出任何东西。 我已经试过了 如果碰撞=true,player.update(碰撞)将矩形更改为红色,如果为false,将矩形变为黑色。 我已尝试使用for和if,例如: 等但这不起作用,它只适用于wit