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 /
  • Help Room /
avatar image
1
Question by Lautaro-Arino · Jan 17, 2014 at 03:46 PM · physicsrigidbodyvelocityaddforce

AddForce instead of modyfing Velocity

I just realized that if i want to use physics with rigidbodies2d i cant move the player or character by modyfing Rigidbody2D.velocity.
So how do i do it?

Im getting the movement input from GetAxis("Horizontal") and i want the character to move left or right depending on this. Its easy if i want to use velocity but how would i convert this to AddForce?

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

4 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by robertbu · Jan 17, 2014 at 04:14 PM

'velocity' and AddForce() are very different. Imagine a space ship heading in some direction and you add some force from the side (perpendicular to the direction the ship is traveling). The ship does not make an immediate 90 degree turn. Instead the force turns the ship towards the new direction some. The more the force, the more the angle of the new direction is different from the old. The current move vector and the force are added together to get the new direction.

With velocity, you get an immediate change in direction. So if your ship was headed directly up in your 2D game and you did:

 rigidbody2D.velocity = Vector3.right;

Your ship would make an immediate turn towards the right. Note you can split the difference somewhat. Rigidbody2D.drag makes AddForce() act more line an immediate velocity assignment. The higher the drag, the faster an object sheds old velocity and takes on new velocity. Of course you have to add more force and continue to add force each frame to overcome drag. As for "Horizontal" and velocity, In FixedUpdate() you can put:

 rigidbody2D.velocity = Vector2(GetAxis("Horizontal") * maxSpeed, 0.0);
Comment
Add comment · Show 7 · 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 Lautaro-Arino · Jan 17, 2014 at 06:54 PM 0
Share

Thanks for the explanation! Very usefull. :) However, i think i read that i should not set the velocity directly if i want physics to work properly. Is this not correct?

This is how it is now and i thought that is what causes the problems?

 rigidbody2D.velocity = new Vector2 (movement * $$anonymous$$axSpeed, rigidbody2D.velocity.y);
avatar image robertbu · Jan 17, 2014 at 08:02 PM 0
Share

Setting velocity does not break the Physics engine with respect to things like collisions. But the behaviors of objects will be less realistic if you set the velocity directly. Cars or space ships do not make immediate 90 degree turns when we attempt to change directions for example.

I'm not sure what problem you are trying to solve with AddForce() vs. Rigidbody.velocity. As a starting point, you can do:

 rigidbody2D.AddForce(Vector2.right * GetAxis("Horizontal") * amount);

You will have to play with 'amount' to see what works for your mass and situation.

avatar image Lautaro-Arino · Jan 18, 2014 at 07:49 PM 0
Share

Tanks! That moves the character and the physics still work as they should.

But it gives me other problems i dont know how to fix. The speed seems acumulative so it just keeps adding upp. When i stop pressing a key the player takes time to slow down so it seems to be skating on ice.

How could i control how long it takes to reach max velocity? How could i make sure a max velocity is not passed? How could i make the slow down faster so the player doesnt skate?

avatar image robertbu · Jan 18, 2014 at 07:57 PM 0
Share

As mentioned in the original answer, Rigidbody.drag controls how long it takes to slow down. Edit 'Drag' in the inspector or it can dynamically be changed in script. As for creating a maximum velocity, you use Vector3.Clamp$$anonymous$$agnitude():

 rigidbody.velocity = Vector3.Clamp$$anonymous$$agnitude(rigidbody.velocity, topSpeed);


avatar image Lautaro-Arino · Jan 25, 2014 at 12:20 PM 0
Share

Problem is that drag also affects the speed with which the player falls.

There has to be some better way. I guess problem is that i want physics to apply, but when walking i dont want to have a an acceleration time or deceleratiion time. I guess im looking for best of both worlds...

I have a strong feeling that somewhere there is someone that knows about this problem or knows exactly what i am thinking wrong. Its like im missing something that i havent learned yet. Thanks for your answer though!

Show more comments
avatar image
2

Answer by Riak157 · Nov 11, 2014 at 02:46 AM

I ran into similar problems as you OP and I tried the Accepted answer. While it worked, manually clamping the velocity is problematic and can make for a confusing applied physics system (it seems bad to mix force and velocity management in practice). An approach that allowed me to maintain one system of speed management was to scale the force applied in terms of the current velocity as a percentage of max velocity.

 float xcap = (rigidbody.velocity.x / maxWalkingSpeed)*moveHorizontal;
         if (xcap > 0) {
             maxVelocityScalerX = Mathf.Clamp( 1.0f - xcap, 0.0f,1.0f);
             movement.x *= maxVelocityScalerX;
                 }
 
         float zcap = (rigidbody.velocity.z / maxWalkingSpeed)*moveVertical;
         if (zcap > 0) {
             maxVelocityScalerZ = Mathf.Clamp( 1.0f - zcap, 0.0f,1.0f);
             movement.z *= maxVelocityScalerZ;
         }
 
         
 
         rigidbody.AddForce(movement*speed*Time.deltaTime, ForceMode.VelocityChange);


This also has an added benefit of allowing your game actors to pass your manually set velocity cap due to outside forces. This helps maintain a more realistic feel to your movement.

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 colinmbo · Oct 05, 2015 at 11:57 PM 0
Share

@Riak157 Hey man, I tried to use this, but I can't get it to work. You've got a ton of variables and I dunno which one is which. I know this is an old post, but you seem to have solved the answer to my problem. I just can't get your code to work. If you could help that would be great.

avatar image Riak157 colinmbo · Oct 15, 2015 at 02:57 PM 0
Share

Sorry man, I wrote this before my first job and getting hounded on my horrible coding styling. I'll clean it up so its a little more understandable.

avatar image
0

Answer by paledust · Oct 15, 2015 at 07:12 AM

I got the same problem and fixed it, NARROWLY since some remains to be test more. As for that you can't use the velocity or the force added to it will be in vain. So my solution is to set a limitation speed for CONTROL, meaning that you can only control the character within some speed using "addForce" function and since I can only control the horizontal direction, the limitation should just be for "x Axis", instead of the magnititude of the velocity. Here is the code.

             if(Input.GetButton(m_HorizontalInput))
             {
                 if(Mathf.Abs( GetComponent<Rigidbody2D>().velocity.x )<= MoveSpeed)
                     GetComponent<Rigidbody2D>().AddForce (Vector2.right*Input.GetAxis(m_HorizontalInput)*Accelerate, ForceMode2D.Impulse);
                 else
                 {
                     GetComponent<Rigidbody2D>().velocity = Vector2.Lerp(GetComponent<Rigidbody2D>().velocity,Vector2.up * GetComponent<Rigidbody2D>().velocity.y,Time.deltaTime * 5.0f);
                 }
             }
             else
             {
                 GetComponent<Rigidbody2D>().velocity = Vector2.Lerp(GetComponent<Rigidbody2D>().velocity,Vector2.up * GetComponent<Rigidbody2D>().velocity.y,Time.deltaTime * 5.0f);
             }








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 dCalle · Jun 12, 2016 at 09:54 PM 0
Share

why don't you define something like Rigidbody2D pete = GetComponent<Rigidbody2D>(); in the beginning and politely ask pete to change his velocity ins$$anonymous$$d of bugging the compiler with the too many fetch and forget GetComponent calls? ;-)

avatar image
0

Answer by mgreene1 · Mar 19, 2016 at 05:13 AM

This is similar to how Mario handles physics-based movement:

 rigidbody2D.velocity = new Vector2(CrossPlatformInputManager.GetAxis("Horizontal"); * yourMoveSpeed* Time.deltaTime, rigidbody2D.velocity.y);

what this does is slowly accelerate up to your movement speed, then decelerate when you stop moving left or right. You can see that the deltaTime is accessed to make sure this is handled precisely. Don't try to use a '+=' with velocity, either, it will make you move insanely fast, as it will keep increasing your velocity forever. (remember += means that the new value is being added to the old, then set as the new value)

Unity would really benefit from creating a series of tutorials where they teach you how to emulate controls in other games, rather than giving you the most basic way to accomplish something. I'd appreciate it, anyway.

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

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

24 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Rigidbody.velocity Movement code produce wildly different gravity interactions 0 Answers

Why Does Bounciness Affects Rigidbody Velocity? (SOLVED) 0 Answers

Keep gravity while adding velocity to a Rigidbody? 1 Answer

Vector3 Help - Calculating velocity toward a point 1 Answer

Counteracting rigidbody velocity using AddForce? 0 Answers


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