Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 Relan42 · Apr 14, 2020 at 01:24 AM · c#controllerphysics2d

My character loses or gains height inconsistently, how can I fix it?

My concept is that my character should be able to jump to any height it has been, so for example, if my character falls 10 meters then he should be able to jump 10 meters, no more no less. The problem is that sometimes when the character jumps it will lose height, and sometimes it will gain height, and I have no idea why. It usually only gains or loses like 1 meter. Here's my code:

     public float timer;
     public float vy;
     public float uy;
     public float g;
     public Rigidbody2D rb;
     public float maxHeight;
     public float E;
     public float vE;
 
     private float ti;
     private float tf;
     private float vx;
 
     void Awake (){
         maxHeight = rb.position.y;
     }
 
     void Start () {
 
     }
         
 
 
     void Update () {
         if (rb.position.y > maxHeight) {
             maxHeight = rb.position.y;
         }
 
     
     
 
         if (Input.GetKeyDown ("space")) {
             uy = vE;
             ti = tf;
         }
 
         if (Input.GetKey (KeyCode.Mouse1)) {
             ti = tf;
             uy = 0;
         }
 
     
     }
     
 
 
 
     void FixedUpdate () {
 
         timer = tf - ti;
 
         tf = Time.fixedTime;
 
         vy = uy + (g * timer);
 
         rb.velocity = new Vector2 (vx, vy);
 
         E = (rb.position.y - maxHeight) * rb.mass * g;
 
         vE = Mathf.Sqrt (2 * (rb.position.y - maxHeight) * g);
     }
 
     
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Scribe · Apr 14, 2020 at 06:30 PM

There are two answers here, due to having learnt a bit more about the physics engine. The first answer assumes a perfect simulation which Unity is not! It describes how you would find the answer in a maths exam or for the real world, however as Unity physics is applied at fixed intervals rather than continuously it results in some quite significant errors if used in Unity.

The second solution (scroll about half way down and look for the Edit header) is a better solution for mirroring what happens in Unity, it calculates the speed required while taking into account that the acceleration will only be applied in fixed intervals.

If you want the perfect world answer look at The theoretical solution, unfortunately while this would be nice, it's not normally the one you want unless you are building software to do maths for the user!

If you want the solution that will get you the best results when mimicing Unity look at The unity physics solution.


The theoretical solution

A little hard to follow all the two letter vars, but this is how I'd go about it.

Firstly I'd simplify things by moving all of the calculation into FixedUpdate, and just set a boolean jump in Update.

Next, let's have a look at the equations of motion:

equations of motion

s is the distance we wish to travel, which we know as the difference between our current position and maxHeight.

u is the starting speed which is what we want to find out

v is the speed at the end, which we know, as at the top of our jump, speed must always be 0 (since as we go up our speed is positive and when we come down our speed is negative).

a is acceleration which in your case is just gravity.

t is the time it takes, we don't know this information.

So since we don't know t lets use equation 4 as it doesn't include it!

v^2 = u^2 + 2as

we want to find out u and we know v is 0, so lets rearrange it to u = sqrt(-2as)

You can't sqrt a negative number but this works out as we know s is always positive (jumping upwards) and a is always negative (gravity pulls us down) so -2as will always be non-negative.

now we just need to calculate s since we know a is the constant -9.81.

s will be maxHeight minus our currentHeight.

 public Rigidbody2D rb;
 public float maxHeight;
 
 private float g;
 private bool jump = false;
 
 void Awake (){
     maxHeight = rb.position.y;
     g = Physics.gravity.y;
 }
 
 void Update () {
     if (rb.position.y > maxHeight) {
         maxHeight = rb.position.y;
     }
 
     if (Input.GetKeyDown ("space")) {
         jump = true;
     }
 }
 
 void FixedUpdate () {
     if(jump){
         float distance = maxHeight - rb.position.y;
         yVelocity = Mathf.Sqrt(-2 * distance * g);
         rb.velocity = new Vector2(0, yVelocity);
         jump = false;
     }
 }

Hope that helps!


EDIT

The unity physics solution

This is going to get a bit mathsy but there's a solution at the end if you don't care!

So I had a chance to test this out a little and as observed there is a reasonable difference with the planned height and the actual height reached. I am pretty sure this comes from the fact that Unity resolves physics every Time.fixedDeltaTime (usually 0.02) seconds, while the equations above are exact solutions.

I've thrown a bit of maths at the problem and I think I have got a solution that appears to be significantly more accurate, basically by copying what I think is happening in Unity's calculations and taking steps of Time.fixedDeltaTime when working out speeds and accelerations.

using the same variable meanings above as well as n being the number of FixedUpdates passed, and dt being fixedDeltaTime (0.02), we can predict the distance travelled in unity after the number of frames n as:

 s = (u + a*dt)*dt + (u + a*dt + a*dt)*dt + ... + (u + n*a*dt)*dt

Since in 1 frame we travel the speed u plus the acceleration over the time a*dt.

We can simplify a bit:

 s = n*u*dt + a*dt*dt + sum_i=0->n(i)
 s = n*u*dt + a*dt*dt*n*(n+1)/2

Then we need to solve for u:

 n*u*dt = s - a*dt*dt*n*(n+1)/2
 u = s/(n*dt) - a*dt*(n+1)/2
 u = s/(n*dt) - a*(n*dt)/2 - a*dt/2

Now we need to work out the value of n, which is the number of frames over which the jump will reach it's peak, fortunately we can fall back to equation of motion 5 for this, since we don't know u yet, but we have all the other values.

 s = v*T - a*T*T/2

Remind ourselves that at the top of the jump v is 0 and rearrange for T we get:

 T = sqrt(-2*s/a)

another thing to say about T is that it will be equal to the number of frames n multiplied by the frame length dt, so we have T = n*dt, subbing that in we have:

 u = s/T - a*T/2 - a*dt/2

so now we know all the values on the right, we can find u!

Solution

 public class Jump : MonoBehaviour
 {
 
     public float maxHeight = 5;
     private Rigidbody rb;
     private bool jump = false;
 
     void Start()
     {
         rb = this.GetComponent<Rigidbody>();
     }
 
     void Update(){
         if(Input.GetKeyDown(KeyCode.Space)){
             jump = true;
         }
 
         if(Mathf.Abs(maxHeight-transform.position.y) < 0.02f){
             Debug.Log("getting close " + transform.position.y);
         }
     }
 
     // Update is called once per frame
     void FixedUpdate()
     {
         if(jump && maxHeight - transform.position.y > 0){
             // same as 's' in the maths
             float distance = maxHeight - transform.position.y;
             // same as 'a' in the maths, since it is our only acceleration
             float a = Physics.gravity.y;
             // same as T in the maths
             float totalTime = Mathf.Sqrt(-2 * distance/a);
             float dt = Time.fixedDeltaTime;
 
             float u = (distance / totalTime) - (a * totalTime * 0.5f) - (a * dt * 0.5f);
             Debug.Log(distance);
             rb.velocity = Vector3.up * u;
             jump = false;
         }
         if(jump){
             jump = false;
         }
     }
 }

Comment
Add comment · Show 5 · 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 Relan42 · Apr 14, 2020 at 09:12 PM 0
Share

Thanks for the help, but I tried it and it still doesn't work. I did a test, when the game starts I set the velocity of the object to 10. I also rounded gravity to 10. It should get to 5m exactly, but it gets to 5.3m, and I don't know why is that. If I try any other number I can calculate how high it should go, and it always seems to get a little higher than what it should.

avatar image Scribe Relan42 · Apr 15, 2020 at 02:27 PM 0
Share

Check my edit, didn't expect the errors in the Unity system to be so large, the old solution probably would be correct if you could theoretically reduce the Time.fixedDeltaTime down to zero, hopefully the new approximation should work for you, it does rely on fixedDeltaTime remaining consistent of course!

avatar image Captain_Pineapple Scribe · Apr 15, 2020 at 02:43 PM 0
Share

great post in theory but the 0.02 seconds time interval will as OP already noted really screw with your analytical solution. Best solution here would be to get away from setting velocity directly and using Force ins$$anonymous$$d. This way you can get "exact" results by relying on the unity physics system.

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

713 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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

Distribute terrain in zones 3 Answers

Multiple Cars not working 1 Answer

I can only move left and right with a bluetooth controller, but when wired, it works just fine. 0 Answers

Can't use wasd control in game! 1 Answer

Physics2D.OverlapBoxAll doesn't work correctly 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