Weird rotation when moving

Hello,

I created a map with a heightmap and some textures, and I want my character to move across it with a joystick. The collisions are working fine, but as you can see, he rotates weirdly as I move across the terrain. I assume this has to do with the collision box.

For movement I am using setLinearVelocity.

Any tips on this?

(I tried to upload a video of the explanation, but it got scaled to a size so small when I uploaded that it was useless)
Gif explaining

Hi AT. You might wish to look for a way to set fixedRotation = true… on the impostor… either at BabylonJS impostor-level, or native physics-engine levels. BUT, this might interfere with your character’s turning. (angularVelocity? twisting-dual-impulsing?) :wink:

There is angular damping nearby, too… which, when cranked-up… is ALMOST as stiff as fixedRotation, but COULD still be forced to turn… with a beefy angularVelocity “whack”.

Also, another user told me an idea… using a likely-invisible little-mesh… hovering over the player… and do physics forces against THAT little box. Then hook a physics joint… between that little “player-moving tractor”… down to the actual player impostor. https://www.babylonjs-playground.com/#15AFCG#39 (arrow keys move little gray box, which pulls bigger box, via joint)

The objective… put a “slightly-flexible connector” (a lock/hinge/distance/whatever - joint) between the force… and the thing receiving the force. Player can bounce-around a little bit on the terrain… flex a little as it moves… and all is “nicer” because the player is being “pulled-along” by the joint… from the almighty tractor above. :slight_smile: All in all, it is like your player being moved… via bungee-cords hooked to an overhead-hovering helicopter landing gear. :smiley:

Can you turn-off char animation, and problem is same as before? (probably so)

Just thoughts. Your game looks nice! Hopefully, we’ll hear more comments, soon. I’ll invite @Cedric to come visit… he’s pretty sharp on this stuff. (thx C).

What physics engine are you using, AT? What impostor-shape is installed on the animated character? What are your mass, friction, and restitution values on char? What impostor is set on ground? What are ITS friction/restitution? SO many questions, eh? The more info, the better.

Is there ANY chance you could reproduce the same problem… using our playground application? All 3 of our main physics engine… can be activated in the playground. Making a playground that shows the same issue… would make things SO much easier.

2 Likes

Hey! Thanks for the reply :slight_smile:

I am currently using a box as the collider and making it invisible. I was thinking of fixing the rotation somehow, but I thought that I would probably run into other problems because of it.

Yes, I tried with no animation and the problem remains. I think it has something to do with the ground of the map not being perfectly plane.

I am using Cannon. I will try to make a playground that works, but that may be kinda hard, since I am using Ionic (my objective is to deploy on mobile)

1 Like

Ok, after some minutes of struggle, I created an example, @Wingnut!
https://www.babylonjs-playground.com/#W5ESRI#2

Please forgive the messy code, I was kind of in a hurry :slight_smile:
If you move the joystick you can see the weird rotation

1 Like

Alright, AT! Nice job on the playground version… excellent. NOW we can start doing some sniffing. I’m thinkin’… continuously-dumping character.physicsImpostor.physicsBody.quaternion… to console (during moves)… see if that puppy is spinning around. Almost surely it is.

Cannon has a toEuler() on their quaternions, too, but it’s different to use than the BJS toEulerAngles(). So, we can probably “watch” the quat on the physicsBody… by simply watching the mesh root.rotationQuaternion.toEulerAngles()… easily.

Virtual joystick, huh? I haven’t seen one of these in YEARS. (just kidding)

VJ’s… have a strange phenomenon… they create an extra canvas across the entire screen… which blocks the editor portion of the playground… so ya can’t edit code. Artur is going to add a nice “delete extra canvas if VJ not in-use (after 15 seconds?)” - addition, soon, (wink)… but until then…

IF you can’t get editor portion of playground to “focus” after using the drag-on-canvas virtual joystick… then you CAN…

Open F12 dev tools, choose “inspector” tab if you have one, scroll to bottom of html document, and delete ALL <canvas> elements from the bottom of the document. THEN, the PG editor can be focus’d again… and edits can happen. Interesting adventures ahead!

PS: Awhile back, a few of us idiots were playing with a “drag-puck” controller made from BabylonJS GUI system (no extra canvas needed for virtual joystick)… https://www.babylonjs-playground.com/#91I2RE#65 This whole 91I2RE series is full-of experimental mouse-draggy circular things… it was an experimental spin-off from @adam’s colorpicker GUI control. We made some ipod controllers and assorted drag-puck junk, never producing an “official” GUI control.

ANYway… that PG series is failing from broken context.save() for some reason. Not sure what the story is… on those. BUT… potentially, there is a “better than virtual joysticks” system somewhere in all that mess… if wanted.

1 Like

Hi @Artur_Trapp

I suggest you to use a sphere for collision instead of a box. The collisions will be easier to manage and the movements will be more progressive as the sphere will roll.

Then, instead of attaching the character to the collider, set the character position manually as the center of the sphere. This way, the sphere orientation will not make the character roll.

If you want the character to be more properly adjusted to the terrain (get feet adjusted on the ground ), you can do a raycast from the sphere center downward. The raycast will return the position and normal of the terrrain.

So basically, the idea is to uncouple the physics from the character by keeping what you need (position of collider) but not using the orientation.

1 Like

That is a good point. I never considered the possibility of the problem being the joystick or something, but I will take a look at this new one and try some stuff. I will also fix the playground today so it is editable, thanks for your assistance man :slight_smile:

Nice! The sphere definitely seems like a good idea, I can already see the movement being a lot smoother. I am definitely going to try that as well, thanks!

1 Like

Actually, I don’t think the VJ is causing the unexpected turning. I just wanted to tell about the “block entire webpage” issue of the virtual joystick’s extra canvas. It can get in the way of our playground tests/edits.

I think @cedric’s idea of sphereImpostor… is good good good. It might be a challenge to turn your character if the sphereImpostor is rolling, though. It might cause slow arc-ing turns instead of sharp-angle turns.

Another thing: During the moving, you will need to constantly set player.position = sphereImpostor.position. Probably no big deal… but if a constant polling like that is needed, there is another possibility (or maybe many more). You could contiuously (somehow)… force sphereImpostor to stay “polar” or “upright” while moving (yet not zero-out left/right turns). Then the sphereImpostor would “skid” along the ground instead of rolling. Its round-bottom might eliminate the unexpected turns… but maybe not.

shrug. Thinkin’. :slight_smile:

1 Like

Both for rolling sphereImpostor, and even for skidding sphereImpostor… friction is almost completely gone. (for skidding sphereImpostor, not enough surface contact with ground… friction essentially doesn’t work). SO… your player won’t be able to stop on any angled terrain (hills and valleys) without sliding downward (if your scene has downward gravity). Many use linear and/or angular damping… to bring rolling spheres to a stop, eventually. Only linear damping will work on skidding sphereImpostors.

There is a way to do your own damping. When you need brakes… put this line in onBeforeRenderObservable… in renderloop or in a setInterval…

player.physicsImpostor.setLinearVelocity(player.physicsImpostor.getLinearVelocity().scale(.999)) (smaller number = harder braking. More 9’s = less braking). This method can be used for both linear and angular. You can let it happen continuously, all the time… leaving scale(1) most of the time. When you need braking, change the value in that scale(here) to .99xxx.

You can add functions to onBeforeRenderObservable… but also remove them. You might wish to turn your braking on/off… in that way, instead of adjusting scale(.99 - 1.0).

Lots of interesting experiments to come. Tell/show us stuff you learn, AT, if you would. Thx! I haven’t had time to do any tests on your playground yet… but if you do some… I’ll be watching closely… and so will others.

3 Likes