- Home /
How to set realistic AddForce speed values for walking/running
I have a player character that was at first controlled by rb.velocity.transform times a number that represented miles per hour. The speed worked great, but I wasn't able to do things like jump and run, or fall and move forward. I've been trying out rb.AddForce, but I can't seem to find that sweet spot that I had. The player either goes flying or barely inches along. Does anyone have info on how to convert realworld units into unity units or vice versa? I don't care what kind of system is used, but I need it to be readable for myself which means I can't just use random numbers, even if they look good on screen.
Answer by I5 · Sep 12, 2018 at 04:58 PM
Unity's units are whatever you want them to be and standardize them to be. For example, the mass of your character's rigidbody could have a value of 10. If you wanted, you could make this value of 10 be equal to 10 kilograms or 10 pounds. If you wanted the units to be in kilograms then just make all your other objects with rigidbodies have masses that are relative to the player's character. Ex., if you wanted the units to be in kilograms, and a character's rigidbod had a mass of 10, that would make for an unrealistically light character (unless it was an infant). So, you'd probably want to have a mass of about 75 (rough weight estimate of an average human in Kgs) . Next, you'd want to determine what units you want to use for size/height/distance. Keeping with metric example, you could standardize your objects so that a size/scale of 1 is equal to 1 meter (I think that's the default/assumed scaling for the character sizes in Unity's standard assets). After having determined what you want to standardize you're units on, you can then tweak the amount and type of forces to add, and if you standardized your units to be relative and realistic to our human real world, then your forces will also have real world values. Unity's provided first person character prefab (in StandardAssets), unfortunately, has a mass of 10, so you'd have to set that to something more like 75, and the tweak RigidbodyFirstPersonController.cs until you got the look and feel you wanted. Or, work backwards and keep the mass of 10 and then factor the masses and forces of everything by 10/75 (that's 10 divided by 75, which you'd multiply to factor down sizes and forces). But, I think your wanting to factor up, so you'll have to tweak RigidbodyFirstPersonController.
Thank you, see that's what I've been trying to do (glad I'm not crazy.) I'm not using Unity's controller, I have one made from scratch. I have a model with a capsule collider about 6 units tall, let's pretend that's feet for now. If it's mass is 160 lbs, drag is 1 and the controller multiplies AddRelativeForce (or AddForce) by 3 miles per hour, theoretically everything should work but it's not. You can't even tell the player is moving. I know the obvious answer is to just increase the force value, I'm just fishing for an alternate solution.
(Changing Drag to 0 does nothing)
EDIT: Well, now I can't move at all. I've set walkspeed to 400 and no movement, despite my debugs working. I'm starting to think more is going on here; gravity changes aren't affecting it. Thanks for helping though! :)
EDIT AGAIN: I multiplied everything in hard code by 50, now when I switch to run and sprint I can move normally, but walking still stands still. Heck, I'll just post the code.
private void Update ()
{
//walk
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.W))
{
if (running) //runSpeed = 90
{
playerRB.AddRelativeForce(Vector3.forward * (runSpeed * 50));
//Debug.Log("Running");
}
else if (sprinting) //sprintSpeed = 150
{
//normal movement (very fast, actually)
playerRB.AddRelativeForce(Vector3.forward * (sprintSpeed * 50));
//Debug.Log("Sprinting");
}
else //walkSpeed = 40
{
//no movement
playerRB.AddRelativeForce(Vector3.forward * (walkSpeed * 50));
Debug.Log("Walking");
}
}
can you show a screenshot of the inspector settings? If it's not moving, make sure is$$anonymous$$inematic is NOT checked on the rigidbody (yup drag could be an issue but you'e already tried a 0 setting, i'd leave at 0 until you can get some movement). Also check the rigid body constraints, and uncheck them all until you can get movement and find tune. Lastly, make sure useGravity is checked (I think you already did though). The code you provided is only half the equation, the rigidbody config is the other half. I saw your debug printout code so I think you've already confirmed that in fact force is being added. Just for debugging, you may also want to try to get a reference to the rigidbody each time you use it (i.e getComponent()). You wouldn't go to production with that code but it's just another variable to not have to debug.
Here's the screenshot, I unchecked the freeze rotation and upon pressing forward the model fell over, so there's that.
Answer by Eno-Khaon · Sep 13, 2018 at 11:59 PM
First, addressing your comment with your script:
As a bypass for large multiplications, it's probably reasonable to assume that a character moving "under their own strength" would not necessarily need an arbitrary "muscle strength" factor added in. What do I mean by that?
playerRB.AddRelativeForce(Vector3.forward * (runSpeed * 50));
The 50 multiplied by the runspeed provides an implicit counterbalance against the Rigidbody's mass. If you want the character's added force for movement to be treated relative to their own mass, you can do one of two things:
Multiply the force by the mass of the Rigidbody
playerRB.AddRelativeForce(Vector3.forward * (runSpeed * playerRB.mass));
Or change the ForceMode to automatically ignore mass (for 3D AddForce functions only)
playerRB.AddRelativeForce(Vector3.forward * runSpeed, ForceMode.Acceleration);
As for the main dilemma, that's a problem involving friction. Once you have an object in motion, it stays in motion more easily, so stronger forces to begin to accelerate will generally result in higher speeds once you're going (as well as because these are sliding collider shapes as opposed to realistic limbs, which move in highly complex ways).
To combat friction with the ground, you can look at using Physic Materials to reduce friction (static and/or dynamic) for the sake of movement, but that means having to carefully moderate your character's speed for yourself. You wouldn't have to fight against the physics system trying to provide realistic(-ish) interactions with natural shapes, but you'd instead have to provide your own basis for movement for your character's now-unnatural(-ish) physical interactions.
Edit: Whoops, forgot to add this. One further detail to note...
When you're applying forces to physics-driven objects, you should always apply these forces in FixedUpdate() rather than in Update().
Ah, that might be important! :) I've moved all the walking/running stuff into FixedUpdate() and multiplied by the rigidbody's mass. I'm still getting a lot of the same results; I was with Force$$anonymous$$ode.Acceleration as well. I think I'm going to do some more research and experimentation, hopefully there's a good tutorial out there; thanks a bunch for the help!
Your answer
Follow this Question
Related Questions
Simple rigidbody.AddForce only applying once each time key is pressed 1 Answer
Stop movement of rigid bodies 2D after collision 1 Answer
How to make RigidBody's movement using fixed movement/velocity and other forces all together? 3 Answers
Addforce for shotgun raycasts 0 Answers
Smooth dashing issues 0 Answers