moveWithCollisions sliding on heightmap terrain

Hi, i’m using moveWithCollisions on a heightmap terrain (CreateGroundFromHeightMap).

Unless the ground is perfectly flat, the player slowly slides along the floor, presumably towards flat ground.

The movement code i used was taken from another thread on this forum, so if it isn’t great i’d love suggestions.

Thank you.

function move() {
  if (player) {

let time = performance.now();
// Create a delta value based on current time
let delta = ( time - prevTime ) / 1000;

velocity.y += scene.gravity.y * delta;


let rotation = new BABYLON.Vector3(0,0,0);
if (player.rotationQuaternion) {
  rotation = player.rotationQuaternion.toEulerAngles();
}


if (controls["87"]) {
  player.moveWithCollisions(new BABYLON.Vector3(-parseFloat(Math.sin(rotation.y)) / moveSpeed, 0, -parseFloat(Math.cos(rotation.y)) / moveSpeed))
} else {
}
if (controls["83"]) {
  player.moveWithCollisions(new BABYLON.Vector3(-parseFloat(Math.sin(rotation.y)) / -moveSpeed / 3, 0, -parseFloat(Math.cos(rotation.y)) / -moveSpeed / 3))
} else {
}
if (controls["68"]) {
  player.rotate(BABYLON.Axis.Y,0.03, BABYLON.Space.WORLD);
}
if (controls["65"]) {
  player.rotate(BABYLON.Axis.Y,-0.03, BABYLON.Space.WORLD)
}

if (!controls.inAir) {
  if (controls["32"]) {
    console.log('should jump...')
    velocity.y = 200 * delta
    controls.inAir = true
  }
}

player.moveWithCollisions(velocity)
prevTime = time;
  }
};

A strong gravity, makes that the character slides on the slopes. Try to decrease the severity to see what it does.

Unfortunately that didn’t help.

This can only be a story of gravity.

Can you do a PG, it would be easier to help.

Sure, i’ll post as soon as i can. Not at home right now.

Sorry I do not understand.

@daimenworrall might be better if you posted a link to the Playground instead of embedding it.

I would prefer to use 0 or normal gravity for movement or you will have some issues later, for sliding you can calculate ground (vertex) angle against character
If angle > 45° f.e you will set gravity to -9.81
You can do couple calculations to set direction of sliding based on angle data.

  • Use raycast to get ground vertex and calculate its angle against player.
  • Somebody on this forum already did this, try find it.

https://www.babylonjs-playground.com/#1T9QGC#1

I’ve changed several little things:

  • camera line 6 We did not see the ground
  • ground.position.y = 0; line 112.
  • player.position.y = 30; line 31: The character was very top and took a long time to land on the ground with a lower gravity
  • the ellipsoid : line 32
  • velocity.y = 0; line 36
  • velocity.y += (scene.gravity.y / 100) * delta; : line 45 (Here by default scene.gravity.y has a value of 9.81. This value works best with physics. I divide it by 100)

It works better now.

However it is normal that with a strong gravity, a character slides along the slopes (as in real life) Now your gravity is low, so if your character jumps, it will take longer to land.

https://www.babylonjs-playground.com/#1T9QGC#2

2 Likes

@daimenworrall We can also use a raycast to check if the player is on a floor. If so, we can make vertical velocity zero.

Made a demo with a slide you can walk up and a pillar you can jump on.
WASD is for movement, and SPACE is for jump.
https://www.babylonjs-playground.com/#3EDS3A#16

3 Likes

Wow that’s a lot, and exactly what i wanted. Thank you <3

2 Likes

@gbz can i be REALLY cheeky and ask if you could edit your playground example to rotate the camera with A and D keypresses? I’ve had a go myself but i’m relatively new to the front-end side of development. If not, it’s fine but would really help.

Also, is there a solution for the stuttering when walking down the slope?

Thank you.

Hey @daimenworrall, I tried adding camera rotation with A and D keypresses by adding:

// TODO: How to set the sensitivity/sensibility of camera rotation by these keys?
camera.keysLeft = [68]; // W key
camera.keysRight = [65]; // A key

https://www.babylonjs-playground.com/#3EDS3A#18

However, I’m not sure how to set the sensitivity of camera rotation by A and D keypresses. We can set the sensitivity of camera rotation by mouse movement using

camera.angularSensibilityX = 500;
camera.angularSensibilityY = 500;

@Deltakosh, is there a way to do something similar for keyboard key presses?

@daimenworrall, figured out a workaround to set camera sensitivity on keypresses. In scene.registerBeforeRender(...):

if (keyAPressed) {
    camera.alpha = BABYLON.Scalar.Lerp(camera.alpha, camera.alpha + 0.5, 0.1);
}
if (keyDPressed) {
    camera.alpha = BABYLON.Scalar.Lerp(camera.alpha, camera.alpha - 0.5, 0.1);
}

You can adjust sensitivity by tweaking the numbers 0.5 and 0.1.

https://www.babylonjs-playground.com/#3EDS3A#19

Been thinking about the stuttering of the player while moving down the slide, but not sure at the moment how to fix this. This behavior is dependent on the player’s horizontal speed, scene gravity, and more.

1 Like

Thank you, i really appreciate the help.

1 Like