Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by Ricardo Arango · Dec 05, 2009 at 02:55 AM · physicsrigidbodycharacter

Make rigidbody walk like character controller

I am using a rigidbody to model my character. I have to use it because I need full physics. But the problem is that it accelerates/decelerates when moving. Is there a way to avoid this, so it has constant velocity?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

6 Replies

· Add your reply
  • Sort: 
avatar image
5

Answer by Celtc · Aug 09, 2014 at 02:54 AM

I know I'm a bit late but this may help someone.

The RigidbodyFPSWalker script from the Unity Wiki don't work because it adds the velocity of the object the character is standing on to its own velocity, without checking the nature of this object which may cause a sudden increase of velocity in an unrealistic way. Also, it has an error where it does not make it zero when it's standing over an object which doesn't have a rigid body.

Well I put here the code with some fixes (C#). I think it works quite well now. And here is a LINK to download a sample project. Hope it helps.

 using UnityEngine;
 using System.Collections;
 
 [RequireComponent(typeof(Rigidbody))]
 [RequireComponent(typeof(CapsuleCollider))]
 
 public class RigidbodyFPS : MonoBehaviour
 {
     #region Variables (private)
 
     private bool grounded = false;
     private Vector3 groundVelocity;
     private CapsuleCollider capsule;
 
     // Inputs Cache
     private bool jumpFlag = false;
 
     #endregion
 
     #region Properties (public)
 
     // Speeds
     public float walkSpeed = 8.0f;
     public float walkBackwardSpeed = 4.0f;
     public float runSpeed = 14.0f;
     public float runBackwardSpeed = 6.0f;
     public float sidestepSpeed = 8.0f;
     public float runSidestepSpeed = 12.0f;
     public float maxVelocityChange = 10.0f;
 
     // Air
     public float inAirControl = 0.1f;
     public float jumpHeight = 2.0f;
 
     // Can Flags
     public bool canRunSidestep = true;
     public bool canJump = true;
     public bool canRun = true;
 
     #endregion
 
     #region Unity event functions
 
     /// <summary>
     /// Use for initialization
     /// </summary>
     void Awake()
     {
         capsule = GetComponent<CapsuleCollider>();
         rigidbody.freezeRotation = true;
         rigidbody.useGravity = true;
     }
 
     /// <summary>
     /// Use this for initialization
     /// </summary>
     void Start()
     {
 
     }
 
     /// <summary>
     /// Update is called once per frame
     /// </summary>
     void Update()
     {
         // Cache the input
         if (Input.GetButtonDown("Jump"))
             jumpFlag = true;
     }
 
     /// <summary>
     /// Update for physics
     /// </summary>
     void FixedUpdate()
     {
         // Cache de input
         var inputVector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
 
         // On the ground
         if (grounded)
         {
             // Apply a force that attempts to reach our target velocity
             var velocityChange = CalculateVelocityChange(inputVector);
             rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
 
             // Jump
             if (canJump && jumpFlag)
             {
                 jumpFlag = false;
                 rigidbody.velocity = new Vector3(rigidbody.velocity.x, rigidbody.velocity.y + CalculateJumpVerticalSpeed(), rigidbody.velocity.z);
             }
 
             // By setting the grounded to false in every FixedUpdate we avoid
             // checking if the character is not grounded on OnCollisionExit()
             grounded = false;
         }
         // In mid-air
         else
         {
             // Uses the input vector to affect the mid air direction
             var velocityChange = transform.TransformDirection(inputVector) * inAirControl;
             rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
         }
     }
 
     // Unparent if we are no longer standing on our parent
     void OnCollisionExit(Collision collision)
     {
         if (collision.transform == transform.parent)
             transform.parent = null;
     }
 
     // If there are collisions check if the character is grounded
     void OnCollisionStay(Collision col)
     {
         TrackGrounded(col);
     }
 
     void OnCollisionEnter(Collision col)
     {
         TrackGrounded(col);
     }
 
     #endregion
 
     #region Methods
 
     // From the user input calculate using the set up speeds the velocity change
     private Vector3 CalculateVelocityChange(Vector3 inputVector)
     {
         // Calculate how fast we should be moving
         var relativeVelocity = transform.TransformDirection(inputVector);
         if (inputVector.z > 0)
         {
             relativeVelocity.z *= (canRun && Input.GetButton("Sprint")) ? runSpeed : walkSpeed;
         }
         else
         {
             relativeVelocity.z *= (canRun && Input.GetButton("Sprint")) ? runBackwardSpeed : walkBackwardSpeed;
         }
         relativeVelocity.x *= (canRunSidestep && Input.GetButton("Sprint")) ? runSidestepSpeed : sidestepSpeed;
 
         // Calcualte the delta velocity
         var currRelativeVelocity = rigidbody.velocity - groundVelocity;
         var velocityChange = relativeVelocity - currRelativeVelocity;
         velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
         velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
         velocityChange.y = 0;
 
         return velocityChange;
     }
 
     // From the jump height and gravity we deduce the upwards speed for the character to reach at the apex.
     private float CalculateJumpVerticalSpeed()
     {
         return Mathf.Sqrt(2f * jumpHeight * Mathf.Abs(Physics.gravity.y));
     }
 
     // Check if the base of the capsule is colliding to track if it's grounded
     private void TrackGrounded(Collision collision)
     {
         var maxHeight = capsule.bounds.min.y + capsule.radius * .9f;
         foreach (var contact in collision.contacts)
         {
             if (contact.point.y < maxHeight)
             {
                 if (isKinematic(collision))
                 {
                     // Get the ground velocity and we parent to it
                     groundVelocity = collision.rigidbody.velocity;
                     transform.parent = collision.transform;
                 }
                 else if (isStatic(collision))
                 {
                     // Just parent to it since it's static
                     transform.parent = collision.transform;
                 }
                 else
                 {
                     // We are standing over a dinamic object,
                     // set the groundVelocity to Zero to avoid jiggers and extreme accelerations
                     groundVelocity = Vector3.zero;
                 }
 
                 // Esta en el suelo
                 grounded = true;
             }
 
             break;
         }
     }
 
     private bool isKinematic(Collision collision)
     {
         return isKinematic(collider.transform);
     }
 
     private bool isKinematic(Transform transform)
     {
         return transform.rigidbody && transform.rigidbody.isKinematic;
     }
 
     private bool isStatic(Collision collision)
     {
         return isStatic(collision.transform);
     }
 
     private bool isStatic(Transform transform)
     {
         return transform.gameObject.isStatic;
     }
 
     #endregion
 }
 


Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image seeker0003 · Nov 02, 2014 at 03:02 PM 0
Share

Wow, this is one hell of a script. Nice job.

avatar image Sungold · Nov 27, 2014 at 05:31 AM 0
Share

"it adds the velocity of the object the character is standing on to its own velocity" This must be why if you run over the cubes in the demo scene, the player flies forward incredibly fast. Thank you so much for your script, it avoids that problem very well!

avatar image
2

Answer by rocket5tim · Dec 23, 2009 at 10:23 PM

You might want to take a look at the RigidbodyFPSWalker script on the Unity Wiki.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image dingben · Jul 11, 2010 at 02:26 PM 0
Share

Tried the project on this wiki. Unity had to rebuild it as it was made on a higher version than my 2.6. Seems to work, partially. FPSWalker does not stop moving after a certain amount of 'walking' it... and the direction keyboard keys no longer match the direction the FPS takes on... FPS rapidly falls off the platform to infinity. Will make platform huge to see if I can get a feel for the behavior of the FPS.

avatar image dingben · Jul 11, 2010 at 04:47 PM 0
Share

Was losing the capsule(FPS) in the hierarchy? ...renamed all the cubes 00,01,02,... 10. When hit 'play' the capsule becomes child to cube10(non-terrain-floor)... while using arrow keys to move around, the FPS changes shape and also builds up large speed in any one direction that cannot be compensated by the arrows action... and poof we go to infinity. Don't know if it is due to Unity (versions)conversion or bad C# script... I use javascript, can't comment further until I have had a chance to translate the C# to javascript

avatar image
1

Answer by Ashkan_gc · Dec 05, 2009 at 03:57 AM

you can have constant velocity by disabling friction and drag and setting the velocity of the rigidbody directly to a value. you should not aply forces and you should just use the velocity property and set it to the value that you want. generally it's not a good idea to make your character move in this way. you should use ragdolls when you need physics and use character controllers when you don't need it. simulating human movements with physics is not an easy task and it will become very heavy. there is a great video about physics in unite 08. one of the problem that is described there is "character simulation using ragdolls or rigidbodies".

hope this helps

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by bill · Dec 23, 2009 at 08:14 AM

It may not be the Character Controller see

http://forum.unity3d.com/viewtopic.php?t=39946

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Techsuport · Aug 28, 2011 at 07:50 PM

directly controling Velocity ;)

 var speed:float=4;
 function FixedUpdate(){
     rigidbody.velocity=(Input.GetAxis("Horizontal")*transform.right+Input.GetAxis("Vertical")*transform.forward).normalized*speed;
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DRRosen3 · Feb 24, 2015 at 08:02 PM 0
Share

Doesn't work.

  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Ground clamping a rigidbody on slope 1 Answer

How can I create a "round arc" physics based jump? 2 Answers

Is there a way to draw center of mass on the screen? 1 Answer

RigidBody Character Controller Bug 0 Answers

How to handle walls with my FirstPersonCharacter? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges