babylon101

相机,网格碰撞和重力


相机,网格碰撞和重力

你玩过FPS(第一人称射击游戏)吗?在本教程中,我们将模拟相同的摄像机运动:摄像机在地板上,与地面碰撞,并可能与场景中的任何物体发生碰撞。

我怎样才能做到这一点 ?

为了复制这一运动,我们必须做3个简单的步骤:

1 - 定义并应用重力

首先要做的是定义我们的重力矢量,定义G力。在像地球这样的经典世界中,重力方向沿Y轴向下(负),但随意改变它!

scene.gravity = new BABYLON.Vector3(0, -9.81, 0);

重力可以应用于您之前在代码中定义的任何相机。

camera.applyGravity = true;

2 - 定义椭圆体

下一个重要步骤是在我们的相机周围定义椭圆体。这个椭球代表我们玩家的尺寸:当一个网格与这个椭圆体接触时会发生一个碰撞事件,防止我们的相机太靠近这个网格:

Ellipsoid

babylon.js相机上的椭球属性默认为大小(0.5,1,0.5),但更改值会使您更高,更大,更小,更薄,这取决于调整后的轴。在下面的例子中,我们将使相机的椭球比默认的大一点:

//Set the ellipsoid around the camera (e.g. your player's size)
camera.ellipsoid = new BABYLON.Vector3(1, 1, 1);

请注意,相机的椭圆体是偏移的,以便始终在椭圆体的顶部有视点。您可以通过更新camera.ellipsoidOffset属性来控制此行为。

计算如下:

finalPosition = position - vec3(0, ellipsoid.y, 0) + ellipsoidOffset

3 - 应用碰撞

完成之前的设置后,我们的最后一步是声明我们对感知场景中的碰撞感兴趣:

// Enable Collisions
scene.collisionsEnabled = true;
camera.checkCollisions = true;

并声明哪些网格可能与我们的相机发生碰撞:

ground.checkCollisions = true;
box.checkCollisions = true;

而已!简单!

您可以使用本教程中使用的场景...访问Babylon.js 游乐场演示 -


现在,您的相机将落在y轴上,直到它与地面发生碰撞。并且,当您移动它太靠近它时,您的相机将与盒子发生碰撞。

4 - 对象与对象的碰撞

您还可以通过使用mesh.ellipsoid属性和mesh.moveWithCollisions(velocity)函数对网格执行相同的操作。此函数将尝试根据给定的速度移动网格,并检查当前网格与激活了checkCollisions的所有网格之间是否没有碰撞。

您还可以使用mesh.ellipsoidOffset在网格上移动椭圆体(默认情况下,椭圆体在网格上居中)

var speedCharacter = 8;
var gravity = 0.15;
var character = Your mesh;

character.ellipsoid = new BABYLON.Vector3(0.5, 1.0, 0.5);
character.ellipsoidOffset = new BABYLON.Vector3(0, 1.0, 0);

var forwards = new BABYLON.Vector3(parseFloat(Math.sin(character.rotation.y)) / speedCharacter, gravity, parseFloat(Math.cos(character.rotation.y)) / speedCharacter);
forwards.negate();
character.moveWithCollisions(forwards);
// or
var backwards = new BABYLON.Vector3(parseFloat(Math.sin(character.rotation.y)) / speedCharacter, -gravity, parseFloat(Math.cos(character.rotation.y)) / speedCharacter);
character.moveWithCollisions(backwards);

ArcRotateCamera

ArcRotateCamera还可以检查碰撞,但不是沿着障碍物滑动,当碰撞附加时,此相机不会移动。

要激活碰撞,只需致电camera.checkCollisions = true。您可以使用以下代码定义碰撞半径:

camera.collisionRadius = new BABYLON.Vector3(0.5, 0.5, 0.5)

下一步

太棒了,现在你可以开发一款真正的FPS游戏!但也许你想知道网格何时与另一个网格碰撞?很好,因为这正是我们下一个教程的目的。

进一步阅读

相机概述