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 SmokeyDB · Feb 25, 2014 at 04:09 AM · c#rigidbody2djump

Modify Rigidbody2D Jump distance

I'm using rigidbody2D.velocity to move my character around based on keyboard input. Is there a way to modify the distance portion of the velocity when the character jumps? Right now, the character jumps way too far. I'm currently using addforce, but that doesn't seem to get me what I want. I pretty much want to half the distance while keeping the time the same.

EDIT: Here's my current code for the character controller:

 using UnityEngine;
 using System.Collections;
 
 public class AvaController : MonoBehaviour 
 {
     public float maxSpeed = 5f;
     private bool facingRight = true;
 
     Animator anim;
 
     bool grounded = false;
     public Transform groundCheck;
     float groundRadius = 0.2f;
     public LayerMask whatIsGround;
 
     private float move;
 
     public  bool jumping = false;
     public Vector2 jumpForce = new Vector2(120f, 330f);
 
     void Start() 
     {
         anim = GetComponent<Animator>();
     }
 
     void Update()
     {
         print (rigidbody2D.velocity.x);
         print (jumping);
         // Allow jump in FixedUpdate
         JumpUpdate();
 
         // Play crouching animation
         if( grounded && Input.GetKey(KeyCode.S) )
         {
             anim.SetBool("Crouching", true);
         }
         else
         {
             anim.SetBool("Crouching", false);
         }
     }
 
     void FixedUpdate() 
     {
         // Check to see if the player is touching a "ground"
         grounded = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);
         anim.SetBool("Ground", grounded);
 
         Jump();
 
         // If player is not on the ground, player cannot control the character
         if (!grounded)
             return;
 
         if (anim.GetBool("Crouching") == false)
         {
             move = Input.GetAxis("Horizontal");
             anim.SetFloat("speed", Mathf.Abs(move));
 
             rigidbody2D.velocity = new Vector2(move * maxSpeed, rigidbody2D.velocity.y);    
         }
 
         if( (move > 0) && (!facingRight) )
             Flip();
         else if( (move < 0) && (facingRight) )
             Flip();
     }
 
     void JumpUpdate()
     {
         if (!jumping) {
             if( (anim.GetBool("Crouching") == false) && grounded && Input.GetKeyDown(KeyCode.Space) )
             {
                 jumping = true;
             }
         }
     }
 
     void Jump()
     {
         if(jumping)
         {
             rigidbody2D.AddForce(new Vector2(0f, jumpForce.y));
             anim.SetFloat("vSpeed", rigidbody2D.velocity.y);
             anim.SetBool("Ground", false);
 
             if(rigidbody2D.velocity.x != 0)
             {
                 rigidbody2D.AddForce(new Vector2(-5.8f, 0f));
                 print (rigidbody2D.velocity.x);
             }
             else
             {
                 rigidbody2D.velocity = new Vector2(0,rigidbody2D.velocity.y);
             }
 
             if(rigidbody2D.velocity.y == 0)
                 jumping = false;
         }
     }
 
     void Flip()
     {
         facingRight = !facingRight;
         Vector3 avaScale = transform.localScale;
         avaScale.x *= -1;
         transform.localScale = avaScale;
     }
 }
 

This works perfectly if I comment out the rigidbody2d velocity in my horizontal movement code, but then they character can't move left or right.

Comment
Add comment · Show 10
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 Invertex · Feb 25, 2014 at 04:26 AM 0
Share

In your Horizontal movement code, are you by chance setting the Y velocity to 0? It should be Vector2(horizontal$$anonymous$$ovement,rigidbody2D.velocity.y);

Also, that last line in this code is not doing anything, you're setting rigidbody2D.velocity to itself, that isn't adding anything to the equation.

avatar image SmokeyDB · Feb 25, 2014 at 04:43 AM 0
Share

$$anonymous$$y horizontal movement code is

 rigidbody2D.velocity = new Vector2(move * maxSpeed, rigidbody2D.velocity.y);

It does work, just not how I'm trying to make it work. Right now, the character is moving 10 units when velocity.x is at 1. I only want the character to move 5 units but i don't want to affect the velocity while in the air. I just want a smaller jump.

avatar image Invertex · Feb 25, 2014 at 04:58 AM 0
Share

Your explanation is confusing... If you don't want your horizontal control affecting the jump velocity, then set a condition for if(grounded). Also, you're only setting the grounded bool for your animator, and not this script here. Put the jump code before your movement code, and have it set grounded = false when activated, then your horizontal movement code won't operate until grounded again.

avatar image SmokeyDB · Feb 25, 2014 at 06:08 AM 0
Share

I'll try to explain it a bit more clearly. When the player is running and presses the jump button the character's velocity.y starts increasing until it reaches a certain jump height. It then descends until the player is back on the ground. Currently, there are 10 units in between the starting jump position and the end jump position.

I would like to decrease the jump length from 10 units to 5 units.

avatar image Invertex · Feb 25, 2014 at 07:57 AM 1
Share

That should be as simple as halving the movement calculations you're making then... So I don't see the problem.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Wiki

Answer by Dizmiester · Mar 02, 2014 at 03:29 AM

You're jumping on Update but moving on FixedUpdate? AddForce on FixedUpdate as its a physics calc You can check for the jump button on Update then action it on FixedUpdate.

Adding force is not an incremental thing in your script it just adds a force.

For mass of 1.

force = mass * acceleration

force = 1 x acceleration.

adding force will accelerate the rigid body over time. In the y vector that speed will be restrained by the negative acceleration applied to the rigid body by gravity.

Going up at 330units / sec / sec, but decelerating at 9units / sec / sec. eventually gravity wins and the speed is 0 and you have your max height before you start falling. The max height is set by the time relationship between your jump force and gravity. If you decreased the jump force.y you wouldn't get as high, but wont travel as far because you would be in the air for less time.

You want it to jump as high but not as far?

decreased the jumpForce.x

remember that the jumpForce.x is in addition to your current speed (velocity) so adding force will add acceleration to the velocity of the rigidbody horizontally.

note: (You can try negating the current speed by saying

 rigidbody2D.velocity = new Vector2(0, rigidbody2D.velocity.y);

in the beginning of your jump function. Unless you want to jump further when traveling faster) I've not played too much with using AddForce to move a controllable rigidBody but the logic here makes sense.

It will accelerate slower forwards meaning that by the time the jumpForce.y has taken you up to your height and back down you've traveled forward less. Then when you're grounded the movement calc takes care of slowing you down by setting your velocity.x.

With a bit of trial and error with setting your jumpForce.x you can set a distance in x the rigidbody will move during its rise and fall. There are equations that will allow you to work out -> for any given amount of seconds, when going from a speed of 0, how many meters will you travel if constantly accelerating at N meters per sec per sec. But i don't know them off by heart.

A bit long winded but maybe that helps?

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 SmokeyDB · Mar 02, 2014 at 03:56 AM 0
Share

Thanks for this. It is helpful but still doesn't quite solve my issue. And yea, I want the player to jump as high as I have it right now but not as far.

$$anonymous$$y issue is with the AddForce method. Adding force to the vertical velocity works perfectly fine. The character accelerates upward and accelerates back to the ground based on gravity. Adding force to the horizontal velocity seems to make the character just move forward instantly. It's not a smooth movement like it is when adding force to the vertical velocity.

I can't figure out why adding force to the horizontal velocity would cause a different behavior.

avatar image Invertex · Mar 02, 2014 at 07:20 AM 1
Share

The behavior is different because gravity is vertical... That's how physics works. Also, as I mentioned in my comment earlier, you'r currently Adding Force to your existing horizontal velocity. Ins$$anonymous$$d of using AddForce, just use rigidbody.velocity so that the force isn't added to the existing horizontal force.

avatar image Dizmiester · Mar 02, 2014 at 02:08 PM 0
Share

Ok I understand, as Invertex says the difference is that the upwards force being applied is effected by another AddForce which is automatically applied by the physics engine. So your script adds an upward force and the physics engine adds a negitive force. To understand what is going on you need to have an understanding of how those forces are applied by the physics engine and your script.

The Physics engine is complicated but I'll try and simplify it for sake of explanation.

The physics engine is constantly adding a speed of -9.8m/s every second. If we break this down again it actually adding a speed of -9.8m/s * the time between FixedUpdates or 0.2seconds.

Remember Force = acceleration (if your rigidbody has a mass of 1 ).

accerleration = speed per sec.

So basically every FixedUpdate $$anonymous$$using 1.96m/s from your velocity.y, making it $$anonymous$$us 9.8m/s every second.

avatar image Dizmiester · Mar 02, 2014 at 02:25 PM 0
Share

Your script only works on the next FixedUpdate after Jump() is called

So your script only adds a force for 0.2 seconds (the length of 1 FixedUpdate ) say 120m/s * 0.2seconds giving you a velocity.y of 24m/s at the start of your jump.

Physics Engine then adds gravity every FixedUpdate between then and when you land. gradually slowing your speed until it is 0 then goes into $$anonymous$$us speed which makes you fall.

If you want to have this ramp effect on your horizontal movement, you need to have another force being applied which is the inverse of your JumpForce.x like say "AirDrag"

Setting AirDrag to something similar to gravity would produce the same effect but it would need to be applied over a period of time rather than just one FixedUpdate Say You have a variable called jumping which gets set to true when the jump button is pressed but gets set to false when you land.

Then you could say

 if(jumping){
 rigidbody2D.AddForce(new Vector2(-1.96, 0));
 }

This would slow your speed in the x-axis by 1.96 every FixedUpdate until it was 0 but would then move you backwards so you would need to restrain it by saying something like

 if(jumping){
    if(rigidbody2D.velocity.x > 0){
     rigidbody2D.AddForce(new Vector2(-1.96, 0));
    }else{
     rigidbody2D.velocity = new Vector2(0,rigidbody2D.velocity.y);
    }
 }
avatar image Dizmiester · Mar 02, 2014 at 02:38 PM 0
Share

This would then apply an drag force to your horizontal speed until that speed reached close to 0

I'm not sure if that's the effect you're after but that's how to simulate the physics of what I think your asking.

As Invertex is saying you could do all this by applying changes to the velocity.x and velocity.y ins$$anonymous$$d as that's all that AddForce is really doing anyway.

It just does it in relation to the objects mass variable. If the Rigidbody's mass is 1 then AddForce only called on one FixedUpdate and setting velocity is near enough the same as far as the physics engine is concerned.

Just remember that AddForce is speed over the period that the force is applied ( 0.2 seconds per FixedUpdate ) where as setting the velocity is a command to say

"this is the speed!"

and if you set that speed each FixedUpdate the speed is still the speed. Whereas if you AddForce every FixedUpdate its like saying add this

"speed to the current speed"

Ok as you can see I like Physics and explaining Physics so may have got a bit carried away. I'll go find some other physics based questions to answer now..

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

22 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

Related Questions

How to change the gravity scale of the rigidbody 2d back to it's default value after player lands to the ground from jump 1 Answer

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Unity 2D Jump script wont work on android but does on PC? 0 Answers

Multiplayer - Spawn in the last position 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