我创建了这个函数,在我的渲染循环中调用它来检测碰撞并移动玩家/摄像机(这是第一人称游戏)使用名为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.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;
}
}
Click here for the demo.
WASD要搬家。跳跃的空间(有点)。黑色立方体/矩形镜像摄像机在x轴上的位置+50。在立方体上检测到碰撞。
基本上我有两个问题。我应该使用立方体的顶点来检测碰撞或面部吗?如果一个对象小于立方体,则不会检测到碰撞,因为它不会碰到任何顶点。那么我应该为面部重写它吗?
其次,如何在检测到碰撞时防止立方体下降得太远。如果您检查演示,每当立方体脱落时,它会在停止前停留一段时间。我认为与mPlayer.velocity.y
有关,但我无法修复它。即使是跳跃也会使立方体沉入地下。
答案 0 :(得分:1)
要提高碰撞检测的“分辨率”,可以向多维数据集添加更多顶点,例如当你声明pCube时尝试:
pCube = new THREE.CubeGeometry(100,100,100, 5,5,5);
并且其余代码可以保持不变。
关于较小的物体“在为碰撞检测而创建的光线之间滑动”,通常如果使用此方法但是小物体会创建光线,那么您将更准确地检测到碰撞。