I’m trying to create a infinite runner game, just like the no-internet google dino game, here’s the playground.
Currently the character is the cylinder, using the space bar we can jump but I’m dealing with a issue that the cylinder moves to some directions after a couple of jumps, also, sometimes we can see that the cylinder kind fit on its position again, like a ball rolling on a semi-circle.
On the lines 73 and 74 I’m trying to force the mesh to keep on the same x and z, just like I’ve done with rotation but for some reason the mesh keeps repositioning itself after jump
Also, after I lock the rotation I got a strange bug that the mesh sometimes go inside the ground, commenting line 69 it don’t go inside the ground anymore, but the mesh starts to rotate after a couple of jumps, falling from the ground. This makes me think that could be a better way to prevent mesh to rotate.
So, I have two doubts:
How can I properly prevent my mesh from keep repositioning on x and z?
How can I properly prevent my mesh from rotate on x, y and z?
Some suggestions/things you should try:
Mixing forces/impulses and settting body position and orientation at the same time is a bad idea. Physics engine internal states get mad after a while and you’ll get weird results after a while. It can become incontrollable and I think it’s the case here.
You should try ammojs. It’s more supported than cannon and overall, I think the resolution quality is much better. And you’ll get more controls.
Do not try to constain a body position by setting a new position. Instead, favor changing its angular or linear velocity. Like this:
var vel = player.physicsImpostor.getLinearVelocity();
player.physicsImpostor.setLinearVelocity(new BABYLON.Vector3(vel.x, vel.y, 0));
For angular velocity, set all angular speed to 0 so the mesh will not rotate. Ammojs provides
setAngularFactor
that you can call on ammojs rigid body.Or a more ‘manual’ way is to setAngularVelocity to (0,0,0) each frame.
I already provided the “solution” badge cause this just work! Thank you again @Cedric!
But what you mean by “call ammojs rigid body”? Its something like call this outside the player? I did with the “manual” way, but I would like to understand this other way
And one more thing, I try to use Ammojs but when I replace Cannonjs to Ammojs the project crashed with some errors:
I’m loading the plugin through the babylon CDN https://preview.babylonjs.com/ammo.js and initializing it with scene.enablePhysics(null, new AmmoJSPlugin());. am I doing something wrong?
I had to change a couple of things when switch to Ammo.js
Basically I don’t need to import the CDN anymore with this package importing it as this: import * as Ammo from 'ammo.js';
The othe change I have to made was on the Ammo().then I had to make it on the index.js of the react (where are the ReactDOM.render) wrapping everything inside the .then, as follow:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorkerRegistration from './serviceWorkerRegistration';
import reportWebVitals from './reportWebVitals';
import * as Ammo from 'ammo.js';
Ammo().then(() => {
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://cra.link/PWA
serviceWorkerRegistration.unregister();
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
});