Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by FelixLeChat · Dec 04, 2013 at 09:24 PM · 2drigidbody2dvelocityjump

rigidbody2D : X velocity is slowed down when I jump.

Hi everybody! First question here. :)

From the code I made for a 2D game or even in the Unity 2D demo project, when I jump the velocity.x is maxed at 2 and if I release the arrow key in middle air, the character seems to speed up. Don't know what cause that. At first I tough the problem was on my side but when I tested again the Unity 2D demo project, I noticed the same problem. You'll especially notice it when you release the move key middle air. Cans someone explain this to me or have fixed it yet? Thanks!

Here is my code : using UnityEngine; using System.Collections;

 public class PlayerControlBonhomme : MonoBehaviour {
 
     public float moveForce = 365f;
     public float maxSpeed = 5f;
     public LayerMask groundLayerMask;
     public float jumpForce = 1000f;
 
     private bool faceRight = true;
     private Animator anim;
     private Transform groundCheck;
     private bool jump;
     private bool grounded = false;
 
     // Use this for initialization
     void Start () {
         anim = GetComponent<Animator>();
         groundCheck = transform.Find("groundCheck");
     }
 
     void FixedUpdate () {
         float h = Input.GetAxis("Horizontal");
 
         anim.SetFloat("speed", Mathf.Abs(h));
 
         if(h * rigidbody2D.velocity.x < maxSpeed)
             rigidbody2D.AddForce(Vector2.right * h * moveForce);
 
         // Si la velocité est trop grande, on se créé un nouveau vector2 qui la limite
         if(Mathf.Abs(rigidbody2D.velocity.x) > maxSpeed)
             rigidbody2D.velocity = new Vector2(Mathf.Sign(rigidbody2D.velocity.x) * maxSpeed, rigidbody2D.velocity.y);
 
         if (h < -0.01f && faceRight) {
             Vector3 scale = transform.localScale;
             scale.x *= -transform.localScale.x;
             transform.localScale = scale;
             faceRight = !faceRight;
         }
 
         if (h > 0.01f && !faceRight) {
             Vector3 scale = transform.localScale;
             scale.x = Mathf.Abs (transform.localScale.x);
             transform.localScale = scale;
             faceRight = !faceRight;
         }
 
         if(jump)
         {
             rigidbody2D.AddForce(new Vector2(0, jumpForce));
             jump = false;
         }
 
     }
 
     // Update is called once per frame
     void Update () {
         grounded = Physics2D.Linecast(transform.position, groundCheck.position, groundLayerMask);  
         
         if(Input.GetButtonDown("Jump") && grounded)
             jump = true;
 
         print (rigidbody2D.velocity.x);
     }
 }
Comment
Add comment · Show 1
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 khreenberg · Jan 03, 2014 at 01:17 AM 0
Share

I have this exact same problem. In my own game, as well as thee Tower Bridge Defence example. I would upvote the question, but I can't, since I don't have 15 reputation.

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by HappyMoo · Jan 03, 2014 at 04:16 AM

Damn... answer length is limited.. my answer got cut - I try to distribute on comments...

Oh, the code is not that nice... that's from an official Tutorial? I see multiple problems... and also where the speedup comes from.

Ok, lets try to fix that. I won't check any code in unity, so I might have syntax errors, but you should be able to fix them if you understand the code above.

Here's the first Problem:

 if(h * rigidbody2D.velocity.x < maxSpeed)
    rigidbody2D.AddForce(Vector2.right * h * moveForce);

This is problematic in multiple ways... First you think that this just checks for movement to the right, because it only checks for vel.x not being too big, but what happens if we're moving to the left? Well then h is also negative and a negative vel.x multiplied with a negative h makes it positive again, so you can check against maxSpeed... well so you thought. Because actually, we can still slide/move to the left and then press right to get a positive h, which makes the whole thing negative... which passes the check and doesn't lead to a wrong movement, but the designer clearly didn't think about that case.

Comment
Add comment · Show 11 · 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 HappyMoo · Jan 03, 2014 at 04:21 AM 0
Share

Anyway... the real problem starts when you are at maxSpeed and let go of the buttons. Then h isn't 0 immediately, but is smoothed for keyboard and if you would use an analog stick, you also get values like 0.9 etc.... So you're moving at maxSpeed and h is something like 0.9... well, then

 0.9*vel.x<maxSpeed

and you accelerate although you are already at maxSpeed.

You then try to clamp back speed that is too big, but you already added the force and that force isn't applied as an impulse, but as a continuous force - that'S why the AddForce method has an optional Force$$anonymous$$ode parameter - so this means that some of the force is applied over the next frames and moves the character somwhat too far, even when the speed is cut back between frames.

avatar image HappyMoo · Jan 03, 2014 at 04:22 AM 0
Share

Your direction changing code is also confusing, because once you copy the vector into "scale", you have all values in there, why do you access the localscale again? And why do you use two methods to turn the -1 to 1 and 1 to -1? The first time you multiply and the other time you do $$anonymous$$athf.Abs. When you surely know that that value can only be 1 or -1, why not just multiply by -1 both times?

Also the overall Idea, that you throw a force into a black box physics system, but then mess with the system, by not correcting with forces again, but manipulating the velocity directly. You shouldn't manipulate forces and velocity as they are connected. That's like you don't know what you're doing... pushing at A and watching what the system does and then push back at B.

avatar image HappyMoo · Jan 03, 2014 at 04:23 AM 0
Share

You clearly controlling the character over the velocity (at least the horizontal movement), so you should stay within the velocity domain and do the velocity changes yourself directly, not by using forces or rather apply the horizontal force yourself and not throw it into the physics system. Then for the vertical movement it's ok to use forces here, as we don't need to mess with the velocity again and gravity is also an acceleration/force that gets applied in the same direction.

Also, the grounded variable can also be potentially problematic if the jump force isn't enough to get the player outside of the grounded state within a frame, because if it's not enough force, the player could press jump on two consecutive frames and perform an extra high jump. But I can't say if it's really problematic, because I don't know where the groundcheck position exactly is, so this may only be a potential problem, but not show up concretely, so I won't change anything there.

avatar image HappyMoo · Jan 03, 2014 at 04:23 AM 0
Share

Well, let's try to fix this mess... ;)

 float horizVel = 0f;
 static Vector3 mirrorX = new Vector3(-1,1,1);
 
 void FixedUpdate () {
    float h = Input.GetAxis("Horizontal"); // our wish speed between -100% and 100%
    anim.SetFloat("speed", $$anonymous$$athf.Abs(h));
 
    // calculate adding the force ourselves: acceleration = Force/mass ... and clamp the velocity 
    horizVel = $$anonymous$$athf.Clamp(horizVel + h*(moveForce/rigidbody2D.mass)*Time.deltaTime, -maxSpeed, maxSpeed);
 
    Vector3 vel = rigidbody2D.velocity;
    vel.x = horizVel;
    rigidbody2D.velocity = vel;
       
    if ( (h<-0.01f && faceRight) || (h>0.01f && !faceRight) ){
      transform.localScale = Vector3.Scale(transform.localScale, mirrorX);
      faceRight = !faceRight;
    }
 
    if(jump)
    {
      rigidbody2D.AddForce(new Vector2(0, jumpForce));
      jump = false;
    }
 }
avatar image khreenberg · Jan 03, 2014 at 10:38 AM 0
Share

Thank you for this! :D I have two comments, though: 1) Correct me, if I'm wrong (I'm very new to Unity), but we don't need Time.deltaTime when we're working in FixedUpdate()? 2) You forgot to use the h-variable with the speed, which means there will be no deceleration, unless you change direction with the input. $$anonymous$$y workaround was to multiply it in the Clamp as such: horizVel = $$anonymous$$athf.Clamp((horizVel + (moveForce/rigidbody2D.mass))*h, -maxSpeed, maxSpeed); but I'm not too good with physics, so this might not be the best approach.

Once again, thank you for your reply and explanation of the problem! :D

Show more comments

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

18 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

Related Questions

Convert Force into Velocity for 2D Player Jump 0 Answers

Character slows down when running against a wall (2D) 1 Answer

Projetil rotation in straight line trajectory 2 Answers

Horizontal/Parabolic Projectil Movement and Jump for 2D //HELP! 0 Answers

Rigidbody2D.velocity.x not working but Y does 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