Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 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
2
Question by ishdagz · May 27, 2017 at 01:13 AM · charactercontrollerslopeslide

character controller slide down slope

Hi all, I am using the character controller and am attempting to have the character slide down slopes that are greater then the slope limit set in the character controller. I have tried numerous methods to get it to work consistently that usually involve spherecasts and raycasts to the surface and mathing out the vector with distance hits.

Is there a simpler way to detect the down slope angle of the surface the character controller is standing on so that it can slide down the correct direction? Depending on how the 'Slope Limit' option in the character controller works it is possible that it can be directly read from somewhere? Otherwise how does it know that it has hit that limit if it can't measure it?

I have seen a few similar questions but have not found a way that worked consistently.

Thanks

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 ishdagz · May 29, 2017 at 03:40 PM 0
Share

How does the character controller know if the character has hit the slope limit? Is there something simple I am missing? Just having access to the 'can they move' or not check that is somewhere in the character controller would help quite a bit.

5 Replies

· Add your reply
  • Sort: 
avatar image
24
Best Answer

Answer by AurimasBlazulionis · May 31, 2017 at 05:53 PM

This is something that is not available by default in the character controller. The problem with sliding off the slopes is that gravity pulls the player down, but to slide off the slope, the player has to be pulled sideways to the direction of the slope's normal and that simply does not happen. We will be replacing the default controller.isGrounded and controller.slopeLimit with our own stuff. So set controller's slope limit to something like 80 degrees because we will need that for out code to work.

From my Unet-Controller:

Get the ground normal using OnControllerColliderHit

 void OnControllerColliderHit (ControllerColliderHit hit) {
     hitNormal = hit.normal;
 }

Then, after the controller.Move, determine if the controller should be grounded or not:

 isGrounded = (Vector3.Angle (Vector3.up, hitNormal) <= slopeLimit);

Then, before calling controller.Move, add sideways speed to allow it go down:

 //Character sliding of surfaces
 if (!isGrounded) {
     inpRes.speed.x += (1f - hitNormal.y) * hitNormal.x * (1f - slideFriction);
     inpRes.speed.z += (1f - hitNormal.y) * hitNormal.z * (1f - slideFriction);
 }

Experiment with the slideFriction value, 0.3 works rather well.

This should do the trick for you.

Comment
Add comment · Show 8 · 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 EpsilonQoppa · May 31, 2017 at 06:29 PM -1
Share

Damn, that's sexy. +1 for elegance.

avatar image ishdagz · Jun 01, 2017 at 03:44 PM 0
Share

Thanks, it works almost perfectly, but I do have some odd speed changes when it gets to the bottom of the slope and some issues where I can keep going up in certain situations. The latter are most likely due to how my movement vector is initially calculated. The former is not bad, I will post video later if I can. Overall much simpler then my last solution with multiple sphere and raycasts!

Also: This method should work on any surface right? Regardless of the rotation of the game object? (On terrain, for example?)

avatar image yaakovyitzchakbenmoshe · Feb 01, 2019 at 05:19 AM 1
Share

Hi cool method, although there's two things that are happening for me: (1) when I begin to run into the slope, the character jitters as he runs into it (and is set back instantly), also (2) when he jumps into the slope, he bounces back sometimes. Do you know how to fix this by any chance?

avatar image GlitchyPSIX yaakovyitzchakbenmoshe · Apr 27, 2019 at 04:19 AM 0
Share

Hello, I currently am facing the same issue as yaakovyitzchakbenmoshe, any wall just makes the character bounce off, and staircases that use the "step offset" will also often make the character bounce off the small "wall" there is.

avatar image Coulomb1 GlitchyPSIX · Aug 23, 2021 at 10:01 PM 0
Share

Is there a solution for this yet?

Show more comments
avatar image Fecus · Aug 21, 2020 at 04:40 AM 1
Share

I know this is an old post but i was trying to use this in my game, and repurposing it for general gravity stuff and am getting some weird results where isGrounded is returning true when Vector3.Angle (Vector3.up, hitNormal) is 0. Basically the only time it says the character is not grounded is when they are touching a slope. Is this the intended behavior and i need to make something completely separate for gravity? `` `` void FixedUpdate() {

 hitAngle = Vector3.Angle(Vector3.up, hitNormal);
 isGrounded = (hitAngle <= myController.slopeLimit);
 

 if (!isGrounded)
 {
     velocity.y += gravity;
     velocity.x += (1f - hitNormal.y) * hitNormal.x * (-gravity - slideFriction);
     velocity.z += (1f - hitNormal.y) * hitNormal.z * (-gravity - slideFriction);
 }
 else
 {
     velocity.y = -2f;
     velocity.x = 0f;
     velocity.z = 0f;
 }
 myController.$$anonymous$$ove(velocity);

} `` `` also wondering if @marclar83 could help.

avatar image qwerto227 Fecus · Jan 12 at 07:38 PM 0
Share

As far as I can gather indeed this just deter$$anonymous$$es whether or not the character is on a slope and should slide, and does nothing to deter$$anonymous$$e whether or not the character is "grounded", I have seperated them out into grounded and sliding, do all the standard grounded checks and then just add the sliding velocity if the character is on a slope greater than the limit.

avatar image
8

Answer by marclar83 · Oct 07, 2017 at 08:33 PM

@AurimasBlazulionis' script worked very well, but I had to tweak it to work with the default FirstPersonController. To help newcommer to undate the actual Unity official script, I've made a few minor adjustments. Oppositly to the original slopeLimit, I've set a much lower value (like 40 instead of 80, for the script to work). First, we need to define the variables at the beginning of the scripts:

 private bool isGrounded; // is on a slope or not
 public float slideFriction = 0.3f; // ajusting the friction of the slope
 private Vector3 hitNormal; //orientation of the slope.

Get the ground normal by adding this line in the void OnControllerColliderHit:

 private void OnControllerColliderHit(ControllerColliderHit hit)
 {
    hitNormal = hit.normal;
    ...

Then, after the m_CharacterController.Move (in the FixedUpdate), determine if the controller should be grounded or not:

 isGrounded = Vector3.Angle (Vector3.up, hitNormal) <=  m_CharacterController.slopeLimit;

Then, before calling m_CharacterController.Move (in the FixedUpdate), add sideways speed to allow it go down:

 if (!isGrounded) {
     m_MoveDir.x += (1f - hitNormal.y) * hitNormal.x * (speed - slideFriction);
     m_MoveDir.z += (1f - hitNormal.y) * hitNormal.z * (speed - slideFriction);
 }

Thanks again @AurimasBlazulionis for your great help, all credit goes to that person !

Comment
Add comment · 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
2

Answer by chris_sarama · Aug 01, 2017 at 02:35 PM

To improve upon @AurimasBlazulionis answer I found it better to multiply a slide speed at the end of the formula. The problem with his friction method is it can only go so fast no matter how low you put the friction.

 slideDirection.x = ((1f - hit.normal.y) * hit.normal.x) * slideSpeed;
 slideDirection.z = ((1f - hit.normal.y) * hit.normal.z) * slideSpeed;


A slideSpeed of 6 works pretty well. This slides very fast and is much more realistic.

Comment
Add comment · 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
0

Answer by ChiliStudio · Dec 16, 2019 at 10:38 AM

// ON START() CREATE SLIDE TRANSFORM

     slideGameObject = Instantiate(new GameObject(), transform);
     slideGameObject.name = "UsedForSliding";
     slideTransform = slideGameObject.transform;


// FIND THE POINT WE HIT void OnControllerColliderHit(ControllerColliderHit hit) { collisionPoint = hit.point; }

 RaycastHit groundHit;
 Ray groundRay;
 
 // on Update:
 
         groundRay.origin = collisionPoint + Vector3.up * .05f;
         groundRay.direction = Vector3.down;
 
 
         
         slideTransform.rotation = transform.rotation;
 
 
 
         // IF WE ARE ON A SURFACE, DETERMINE IF WE SHOULD BE SLIDING
 
         if (Physics.Raycast(groundRay, out groundHit, .6f)){
 
 
             
 
             slopeAngle = Vector3.Angle(transform.up, groundHit.normal); // The angle of the slope is the angle between up and the normal of the slope
 
             if(slopeAngle <= playerCC.slopeLimit) // if angles arent too high
             {
                 sliding = false;
             }
             else if(slopeAngle > playerCC.slopeLimit) // if angles are too high
             {
                 if (groundHit.transform.gameObject.tag.Contains("Sl") & playerCC.velocity.y <= 0)
                 {
                     sliding = true;
 
 
                     Vector3 groundCross = Vector3.Cross(groundHit.normal, Vector3.up);
                     slideTransform.rotation = Quaternion.FromToRotation(transform.up, Vector3.Cross(groundCross, groundHit.normal)); // collect the transform of the ground we need to slide down
                 }
 
             }
 
 
         }
         else
         {
             sliding = false;
         }
 



NOW WHEN WE CALL THE CHARACTER CONTROLLER MOVE:

 // IF SLIDING, MOVE THE PLAYER ALONG SLIDE DIRECTION
 
 
 
             if (!haveGottenVelY) // if this is the first frame we are sliding
             {
                 slideVel = playerCC.velocity.y; // get our vertical velocity
                 slideVel = Mathf.Abs(slideVel); 
                 haveGottenVelY = true; // tell computer to no longer get our vertical velocity so we can lerp it
             }
 
 
             slideVel = Mathf.Lerp(slideVel, 180, slideAcceleration); // accelerate the velocity of the slide from our previous Yveolcity to max fall speed which is around 180 (I reccomend slide acceleration of .005)
             slideDirection = -slideTransform.up * slideVel; // set slide vector
 
 
             // APPLY MOVEMENT 
 
             playerCC.Move(slideDirection * Time.deltaTime);






Lastly, make sure to include "Sl" in the tag of any game object you wish to allow sliding on. (Some objects like movable cubes you probably wouldn't need to slide down).

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 NinjaPlayground · Mar 26, 2020 at 10:57 PM 0
Share

If anyone can help me modify the Oculus Integration package code for the OVRPlayerController to do this slope sliding thing, it would mean the world to me!

I'm not a programmer so doing this is a monumental task for me. I attached my current modified version of the OVRPlayerController.cs in txt format.link text

ovrplayercontroller.txt (19.0 kB)
avatar image
0

Answer by Paul_Hughes · Nov 23, 2021 at 05:08 PM

Having trouble altering the new starter assets ThirdPersonController to slide down slopes. The m_moveDir.x I am having trouble as I am swapping it for _input.move.x, but the player automatically moves along that axis, so it is calling it to move somehow in my code or I'm putting that code in the wrong place. It would be nice to see a full script as to how this is all put together instead of snippets and saying it goes above calling controller.Move etc, as there is a call for Move(); in the update and also in the Move function itself controller.Move, so does the code go above and below inside the Move() function or in the actual update method, or should I remove Move() to a fixedUpdate for physics performance? The old Motor script had that ability so why take it out? I have tried half a dozen solutions and YT videos to no avail. It seems my Mathematics and Physics for Unity needs an upgrade, being an indie dev time is not on my side. I keep getting my player bobbing up and down above the surface or no reaction to sliding down the hill at all on the terrain. 2 weeks later and still can not get it to work. I will come back to this in another couple of weeks as my head is on fire. Thank you for everyone's help so far!

Comment
Add comment · 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

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

91 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

Related Questions

How do I make my character fall off slopes grater than its slope limit? 0 Answers

CharacterController Slope Limit not working, character climbs onto everything 0 Answers

CharacterController Slope Problems 0 Answers

Character Controller colides while sliding 1 Answer

3D Character controller jittering when jumping against a small wall 2 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