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 S_Byrnes · Nov 20, 2015 at 04:40 AM · c#addforcenormalsoncollisionstaycontacts

Force Of Jump Determined By Collision.Contacts

Hey guys, I'm a tad stuck here, I need some guidance on how to go about making my jump force be directly associated with the angle of the wall it's bouncing off of.

I have the angles right, using contacts.normal, but when it's bouncing off of say a 45 degree slope, it will have the same force it's using when it jumps upwards, which isn't what I want since on flat ground, it's fighting against gravity, so it only goes so high, but it's only half gravity effect when jumping from a slope.

So what I need is to be able to have my variable called 'jumpDistY' to vary depending on the angle it's jumping from, so if it's on 45 degrees I only want about half strength, if it's 90 degrees I want it to only be about 10-20% of it's total strength.

And every degree in-between should be covered somehow, because I will be creating levels that have varying degrees of slopes so it needs to be able to work on all degrees.

Here is what I have for my jumping and collisions so-far:

 void Update()
 {
 if (Input.GetButton("Jump") && canJump)
                 {
                     canJump = false;
                     GetComponent<Rigidbody>().AddForce(normalDirection* jumpDistY * Time.deltaTime);
                 }
 }
 
 void OnCollisionStay(Collision theCollision)
 {
     if (theCollision.gameObject.tag == "Ground")
     {
         onGround = true;
         canJump = true;
         normalDirection = theCollision.contacts[0].normal;
     }
 }

If you might know how I could achieve this I'd very much appreciate it, thank you!

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

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Metastable · Nov 20, 2015 at 07:40 AM

Well you have the normal so all you really need is to get the magnitude of it in the y direction (0, 1, 0), or Up. We know that normals have a magnitude of 1 so you could just do normalDirection * normalDirection.y. This gets you partially there because when the normal is Up (0, 1, 0) you'll be multiplying by 1 and when the normal is pointing right/left or horizontal the y component will be 0 and thus give you no jump distance. Depending on what you're looking for beyond 45 degrees you could just normalize your jump force such as (.6 * normalDirection.y) + .2 which will give you half strength at 45 degrees because y will be .5, so .6 * .5 = .3, and then add in the extra 20 percent, .3 + .2 = .5, and give you just 20 percent at 90 degrees when the y component is zero. This of course doesn't cover every case because when the floor is completely flat you'd only get 80% full force.

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 S_Byrnes · Nov 20, 2015 at 09:02 AM 0
Share

I see, that's a very good idea, thank you, I'll give the first part a shot, but I'm confused on how I might intuitively set 20% for say the 90 degree angle, would you know what function I could use to achieve this?

Thanks for the answer too, I really appreciate it!

avatar image
0

Answer by rutter · Nov 20, 2015 at 07:02 AM

Most likely you'll need to start with a function like Vector3.Angle or Vector3.Dot to compare against Vector3.up.

For example, you could use lerp to create a linear falloff as the angle approaches 90 degrees:

 float angle = Vector3.Angle(Vector3.up, normalDirection);
 angle = Mathf.Clamp(angle, 0f, 90f);

 //angle between 0 and 90, so express it as ratio from 0 to 1
 float jumpPerc = angle / 90f;
 float jumpForce = maxJumpForce * jumpPerc;
 rigidbody.AddForce(normalDirection * jumpForce, ForceMode.Impulse);

That's relatively simple.

Some developers like to compare vectors using dot products. The dot product of vectors will range from 1 (same direction) to 0 (perpendicular) to -1 (opposite direction). This is handy when you need to check if one character is looking at or away from another character.

For any two vectors A and B with angle theta between them, the dot product is a float that equals |A| * |B| * cos(theta). Since we're comparing unit vectors, here, the dot product is really giving us cos(theta). That's handy because it's a smoother falloff:

 float jumpPerc = Vector3.Dot(Vector3.up, normalDirection);
 float jumpForce = maxJumpForce * jumpPerc;
 rigidbody.AddForce(normalDirection * jumpForce, ForceMode.Impulse);

The math behind this method is a bit more complex to understand, but it's simpler and more consistent in practice.

You can use anything along those lines. Once you've got a jumpPerc from 0 to 1, there are plenty of mathematical functions you could use to modify the jump strength -- you just need to find one that suits your needs!

Comment
Add comment · Show 3 · 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 S_Byrnes · Nov 20, 2015 at 07:22 AM 0
Share

Hey thanks a lot, that's an extremely detailed answer, I really appreciate that!

So what you're saying is I could use either one of those code block principals to get this to work?

This is a lot to wrap my head around, the last code option you wrote looks a bit easier to understand, I think I get it, but what would I need a math function for? (I assume you mean a $$anonymous$$athf.something, right?)

avatar image rutter S_Byrnes · Nov 20, 2015 at 07:38 AM 0
Share

Happy to help!

Either code block should work -- I prefer the second one, personally, but if one works for you over the other, they're both viable.

As far as the extra math function, that mainly matters if you want to manipulate the relationship between angle and jump force. $$anonymous$$aybe you're happy with the output as-is, or maybe you want to make the difference more dramatic.

For example, this would make vertical jumps much stronger, and horizontal jumps much weaker, while still keeping both jumps within the power range you've already set:

 //numbers from 0 to 1 are interesting
 //if you multiply them together, the result stays between 0 and 1
 //consider the curve x^2 from 0 to 1, for example
 jumpPerc = jumpPerc * jumpPerc;

Programmers often use a whole bunch of "interpolation" functions to work on these sorts of values. It's a subtle design thing, but it gives you a lot of control.

avatar image S_Byrnes rutter · Nov 20, 2015 at 09:00 AM 0
Share

Am I supposed to set a float of jumpPerc up above the Update functions as a specific number, or do I just have it set as you've got it already?

Because it's really weird at the moment, using the second method the wall doesn't give any force at all, but it didn't change anything for angles in-between 0 and 90.

I wonder if I'm doing things correctly though (most likely not given my history), since I can jump on a platform that's say 5 ball lengths wide and if I'm on say the bottom 66.7% of it, it will be a really powerful jump (2x regular it seems) but if I'm just towards the edge, in about the top 33.3% of it, it will give me a nice small jump like I want it.

I think this was happening even before applying your code method too though.

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

32 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

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Kicking object with random direction and force 2D 0 Answers

[C#, 2D] How do I apply force to a player using vector 3 velocity to move 1 Answer

Problems with velocity 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