• 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 NanoEngine · Aug 18, 2017 at 07:21 PM · rigidbody2dphysics2dslopesramp

Rigidbody2D climbing 45 degrees slopes

I have problem with my 2d platformer.

I have created several slopes around the map, which are usually 45 degrees. The problem here is that rigidbody cannot just climb the slopes up with the "small' force (which is enough for player to move, but not to climb). Any solutions?

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
1

Answer by Xarbrough · Aug 18, 2017 at 07:28 PM

Here are some ideas:

  • are you maybe applying the force vector left to right in world space? Then you should rotate the force upwards along the slope. So instead of moving (1, 0, 0), you want to move (0.7, 0.7, 0), or even scale it up to (1, 1, 0), so that you have extra force when going up a slope.

  • secondly, you can make the slopes have a PhysicsMaterial that has less or even no friction, so the player slides up more easily.

I hope this helps, if you need any more specific examples, please post some code and maybe show the inspector for your rigidbodies and colliders ;)

I'm adding a small example project of what I mean:

ClimbingSlopes UnityPackage

It's not a complete 2D controller and doesn't feel juicy yet, but it shows the principle. You can also look at the many official Unity tutorials and live trainings about 2D character controllers. Most of the time, you actually don't want to use AddForce, but write all logic yourself and set the position or velocity directly.

Here is just the script if the link goes down:

 using UnityEngine;
 
 public class Movement : MonoBehaviour 
 {
     public LayerMask groundLayerMask;
     public Rigidbody2D rb;
     public float speed = 10f;
 
     void FixedUpdate()
     {
         float input = Input.GetAxis("Horizontal");
 
         // By default we don't want to move.
         Vector2 forceDirection = new Vector2(0, 0);
 
         // Check for ground underneath.
         RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, 1f, groundLayerMask);
 
         // We can only move when on ground.
         if(hit.collider != null)
         {
             // hit.normal points to the surface upwards direction.
             Debug.DrawRay(transform.position, hit.normal, Color.white);
 
             // If this doesn't point straight up, we are at a slope
             // and should adjust our forceDirection...
 
             // Get a perpendicular vector to the normal.
             // This will point upwards along the slope.
 
             if(input >= 0) // Right
                 forceDirection = new Vector2(hit.normal.y, -hit.normal.x);
             else // Left
                 forceDirection = new Vector2(-hit.normal.y, hit.normal.x);
         }
 
         // Now the green line points in the direction we want to adjust force. 
         Debug.DrawRay(transform.position, forceDirection * Mathf.Abs(input), Color.green);
 
         // We want to scale by the input amount, but not by it's direction
         // because we already picked the direction in our ground check.
         rb.AddForce(forceDirection * Mathf.Abs(input) * speed);
     }
 }

 


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 NanoEngine · Aug 18, 2017 at 07:35 PM 0
Share

None of the method stated above actually helped me. I tried to move (1, 1), though the result wasn't very good. ...and I was using little friction physics material to the character...

avatar image Xarbrough NanoEngine · Aug 18, 2017 at 07:38 PM 0
Share

Post your script and settings ;) maybe there's another problem.

avatar image NanoEngine Xarbrough · Aug 18, 2017 at 07:42 PM 0
Share

I just started a new project for testing.

Here is the code:

     void FixedUpdate()
     {
         Rb2D.AddForce(new Vector2(1, 1) * speed);
         CheckForRamp();
     }

Images:

Rigidbody2D settings: alt text

Physics $$anonymous$$aterial: alt text

Show more comments
avatar image
1

Answer by Bip901 · Aug 19, 2017 at 11:56 AM

I have an idea [untested] [C#]:

Make the player use a stronger movement force when you touch a slope.

 void OnCollisionStay2D(Collision2D coll) {
     if (coll.gameObject.tag == "slope") { //use extra force as long as you're touching a slope
          extraForce = true;
     }
 }

When you are no longer touching a slope, remove the extra force

 void OnCollisionExit2D(Collision2D coll) {
         if (coll.gameObject.tag == "slope")
             extraForce = false;
     }

Now, in the place in your script where you make the player move, add something like this: (I assumed you normally use a force of (1 , 0) when moving the player)

 if (extraForce) {
      Rb2D.AddForce(new Vector2(2, 0.5f) * speed); //Double power + some Y-axis movement
 }
 else {
      Rb2D.AddForce(new Vector2(1, 0) * speed);
 }
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 NanoEngine · Aug 19, 2017 at 12:30 PM 0
Share

I have tried that method with the Raycast (ins$$anonymous$$d of collision, since I thought it was more efficient), and it did work, but I'm trying to look for another solution...

avatar image Bip901 NanoEngine · Aug 20, 2017 at 12:13 PM 0
Share

If it's possible, use a character controller ins$$anonymous$$d of physics. Or always use extra force. Or add some extra friction to the slopes so the player won't slide down.

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

70 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

Related Questions

Rigidbody2D AddForceAtPosition - adds more force the further away the target 1 Answer

Limit mouse position so that player launches same distance 2 Answers

Different collision results in some areas. 1 Answer

How to boxcast where a dynamic rigidbody2D's box collider will be in the next frame? 1 Answer

How would I prevent ghost vertices? 2 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges