question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Movement on terrain

See original GitHub issue

I’m trying to implement players ability to move among terrain (based on heightmap) and experiencing few issues here:

  1. I want to avoid players rotation. It should fall, it should slide down but never rotate.
  2. It should not slide down from easy hills.
  3. It should not be able to climb on steep hills.

drawing 2

Here is a simple video that demonstrate this problems: https://www.youtube.com/watch?v=15X7tLMjsPg

  1. I was manage to avoid rotations doing something like this on EACH frame call:

        this.get('mesh').object.rotation.x=0;
        this.get('mesh').object.rotation.y=0;
        this.get('mesh').object.rotation.z=0;
        this.get('mesh').object.__dirtyRotation = true;

Are there any other ways to avoid object rotation without having to execute some code each frame call? Also I thought I can set setAngularVelocity to 0

this.get('mesh').object.setAngularVelocity(new THREE.Vector3(0, 0, 0));

but for some reason it does not helped

2, 3, I don’t have any idea how to solve this.

Terrain and player materials are set to

1, // medium friction
0 // low restitution

gravity is set to (0, -30, 0 )

Any help are highly appreciated.

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:12

github_iconTop GitHub Comments

1reaction
ghostcommented, Apr 16, 2016

Get ready @SET001, because this may take a while…

For your first problem, if you want a solution without putting it in the physics loop you can set the angular factor of your physijs mesh:

this.get("mesh").object.addEventListener("ready", function(){
    this.get("mesh").object.setAngularFactor(new THREE.Vector3(0, 0, 0));
});

The angular factor of an object is basically a vector determining whether or not the final angular velocities should be applied on the mesh (one number for each axis). So, if the factor is an empty vector, no force would be applied for rotation, thus eliminating rotation. This method only needs to be called once (when your object is added to the world), which is why it is put in a ‘ready’ event.

For your second and third problem, you’re going to have to use a little more thinking. First off, you need to determine at what slope angle the character will stop climbing and start falling. I recommend a number between 40 and 45 degrees, but it is up to you. I’ll use 45 degrees here. Next, for every frame, you need to:

  • determine where the character is standing (what triangle of the heightmap the mesh is on);
  • determine the slope angle (the angle between the triangle normal and the upwards unit vector);
  • take appropriate action for the result (if it’s too steep, disable climbing, or disable sliding if not steep enough).

Now that we’ve got our priorities in order, we can begin. You should probably create a new function dedicated to this process. Then, you need to create a THREE.Raycaster (preferably outside of the new function) with its first parameter, ray origin, set to the character position, and its second parameter, ray direction, set to new THREE.Vector3(0, -1, 0), which will make the ray point directly down. In the function, make the raycaster intersect the heightmap mesh with the .intersectObject method, explained here. After getting an array of intersections, you simply take the first intersection (which is the closest) and pass it on to the next part.

We have the intersecting triangle, but what do we do with it? Well, our next challenge is to find out how steep the triangle is. Fortunatly for us, THREE.js provides a utility function in THREE.Vector3 called .angleTo. Just use the upwards unit vector (a.k.a. new THREE.Vector3(0, 1, 0)) and set the function parameter to the triangle normal.

Finally, we know where the character is on the heightmap and how steep the place where it’s standing. All we have to do now is take action, which can be done with a simple if statement. Check if the slope angle is higher than your limit, in radians (in this case 45 degrees, so about 0.707 radians I think), or if it is lower than your limit, again in radians, and disable climbing / sliding. To achieve the first situation, you can ignore all key inputs so that no code will be run. To achieve the second situation, you can set the linear factor to new THREE.Vector3(0, 0, 0). Feel free to make your own handler.

Some example code:

// Note: I refer to 'player' as character object and 'heightmap' to heightmap object.

// Raycaster init code
var raycaster = new THREE.Raycaster(player.position.clone(), new THREE.Vector3(0, -1, 0));

// Slope limit - the angle that tells when players start sliding down (in radians)
var SLOPE_LIMIT = 0.707; // 45 deg

// Call this every frame!
function heightmapPhysics(){
    var panel, intersects;

    // Always update player position to raycaster!
    raycaster.ray.origin.copy(player.position);

    // Find closest intersection
    intersects = raycaster.intersectObject(heightmap, false);

    if(intersects.length){
        panel = raycaster.intersectObject(heightmap, false)[0].face;
    }

    // Get angle between triangle normal and upwards unit vector
    var slope_ang = new THREE.Vector3(0, 1, 0).angleTo(panel.normal);

    // Take appropriate action
    if(slope_ang < SLOPE_LIMIT){
        // Stop sliding
    } else {
        // Stop climbing
    }
}

Looks easier in JS, right? Hope this helps.

0reactions
kourindouhimecommented, Aug 15, 2020

Also reducing timeStep helps too. Switched from fixedTimeStep 1/60 to 1/180 and objects no longer fall through terrain.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Obstacle Course | Movement Terrain | Wilbraham
Movement Terrain Obstacle Course gym. Our obstacle-based activities and programs combine fun with physical fitness. Happy, Healthy, Strong.
Read more >
Unity Tutorial #04 - First Person Controller and Terrain
Unity Tutorial #04 - First Person Controller and Terrain ... #1 FPS Movement : Let's Make a First Person Game in Unity! Natty...
Read more >
Terrain movement - BoardGameGeek
My question is about hinder and water. Both indicate it cost 2 movement pts to leave the terrain. So does it mean if...
Read more >
Movement Terrain OCR Fitness/Youth Athletics | Wilbraham MA
Movement Terrain OCR Fitness/Youth Athletics, Wilbraham, Massachusetts. 4479 likes · 38 talking about this · 5560 were here. Premier youth athletics,...
Read more >
TERRAIN Movement Examples Flashcards - Quizlet
Study with Quizlet and memorize flashcards containing terms like How many sections are in 'Terrain' and name all of them, Red Brick movement...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found