Prevent rectangle body falling over?

Topics: Developer Forum, Project Management Forum, User Forum
Jun 25, 2012 at 10:22 PM
Edited Jun 25, 2012 at 11:19 PM

Hi. I've created a dynamic body using BodyFactory.CreateRectangle and I've given it a mass of 0.5. I'm trying to use this body as the player's character which can move (left and right) and jump.

It moves fine but it can fall onto its side. Is there a way I can stop it doing this so it's always upright?

Thanks for the help,
Joey.

EDIT: Maybe not completely stop it from falling over, but just make it more unlikely? Is there a way I can change the mass center so it's near the bottom of the body?

Jun 27, 2012 at 10:59 PM

Anyone? :) Any ideas?

Jun 28, 2012 at 12:42 AM

A few suggestions:

- Make your body a FixedRotation=true body. This is usually recommended for player characters unless you need otherwise.

- Center of mass of the body is the sum of the centroids of the fixtures that compose it. You can attach a very heavy fixture offset to the bottom of the body together with the normal fixture (a body can have more than one fixture attached). This will move the center of mass (and center of inertia) to the bottom.

- Make two bodies one heavy at the bottom representing the legs and one lighter at the top head/torso and link them with a weld joint (it's always a bit soft) or something else like a slider joint or revolute for more specific effects like flexing/extending or rotation of the legs.

- Ultimate solution - don't use rectangles at all. You will run into more problems later on like sticking to corners and bumping over obstacles. Use either a capsule (more common in 3D games) or a circle for the bottom and square for the top attached with joints. You can put a motor on the circle for the movement even and it's very effective (like a unicycle thing).

Jun 29, 2012 at 11:54 PM
Edited Jun 29, 2012 at 11:55 PM

Thanks jerrysb! I went with your ultimate solution and it's working great. Still some things I've to change but overall definitely much better. :)

I have another question. If I use this to apply a force to a body:

theBody.ApplyForce(new Vector2(18, 0));

Any idea how I would limit the speed at which it's moving? I want to check the speed and only allow the force to be applied if it's under a certain amount.

Really appreciate the help. :)

Jun 30, 2012 at 11:45 AM
Edited Jun 30, 2012 at 11:54 AM

There is a VelocityLimitController that could be of use but it limits the speed of all objects. 

You can use Linear and Angular Damping to some effect as they will decelerate the body proportionally to the speed.

In general what you probably really want is the body to move at constant speed. To that regard check this tutorial:

http://www.iforce2d.net/b2dtut/constant-speed

P.S: If you went with the circle at the bottom route and you attach it with a revolute joint you can enable the motor on the joint and by setting MaxMotorTorque it would actually limit the max speed of the motor. So you won't need to apply forces - just set the MotorSpeed and the body will move accordingly. There is also a way to implement joint friction by setting MaxMotorTorque to a low value and MotorSpeed to 0. If you then ApplyTorque() to the circle the motor will actually oppose the movement. Very useful. 

Rotational and Linear movement on a wheel are connected there are some formulae to go from one to another. It's a common problem in vehicle mechanics so you can find info easily if you need to convert form one to another.

Check this for some explanations:

http://www.iforce2d.net/b2dtut/joints-revolute

Jul 4, 2012 at 2:28 PM

Hi,

 

when i last worked on the FP team, you could set MomentOfInertia to float.PositiveInfinity to prevent that.

I assume that this value is now called "Inertia" try to set this to float.PositiveInfinity. This should do the trick and prevent your body from falling onto its side :)

 

Cheers,

Daniel