Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

slippery slopes

Discussion in 'Scripting' started by dacloo, Sep 1, 2007.

  1. dacloo

    dacloo

    Joined:
    Jun 30, 2005
    Posts:
    469
    Now "Slippery Slopes" may sound like a game, but in fact its an issue I'm having currently in a platform game.

    The current character controller checks the steepness, but it doesn't make the character slide down the slope until it reaches a not-so-steep part.

    The problem is that I need to move the character in opposite direction of the "steepness". How do I determin, using the character controller, which direction the player should fall to?

    thanks
     
  2. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
  3. dacloo

    dacloo

    Joined:
    Jun 30, 2005
    Posts:
    469
    Hi!

    I am currently using it to determin the 'steepness'
    but I am not sure if normal.y is in fact the correct steepness.

    But the real question: Now I have the normal, how can
    I determin the direction for the character to fall to
    and not make it 'stick' to the mesh?
     

    Attached Files:

  4. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Code (csharp):
    1.  
    2. function OnControllerColliderHit (hit : ControllerColliderHit)
    3. {
    4.     var angle = Vector3.Angle(hit.normal, Vector3.up);
    5.     if (angle > 20)
    6.     {
    7.         var slideDir = hit.normal;
    8.         slideDir.y = 0;
    9.         slideDir = slideDir.normalized;
    10.  
    11.         Debug.DrawRay(hit.point, slideDir * 2);        
    12.     }
    13. }
    14.  
     
  5. dacloo

    dacloo

    Joined:
    Jun 30, 2005
    Posts:
    469
    That worked! The implementation was hard, because it can work against you playability wise. Thanks!
     
  6. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Actually i am very interested in the code you wrote to make it work in practice.
    When I tried it one of the game play problems is actually how to differentiate small bumps and large slopes. Because based on the slope you can run over a tiny bump and you get pushed back?

    Did you find a good way to solve that?
     
  7. dacloo

    dacloo

    Joined:
    Jun 30, 2005
    Posts:
    469
    Hi Joachim,

    Exactly! That was the problem.
    I solved it (partially!) by looking at the moveDirection.y.
    If you are jumping it is y>0. Then I simply ignore the 'bounce back'.

    The code got real complicated in logic (lots of if/thens).
    I also use a coroutine that does this when bumping:

    Code (csharp):
    1. maywalk = false;
    2. yield new WaitForSeconds(0.5);
    3. maywalk = true;
    I can send you the whole (messy) code but it is really specific to this particular
    game (not a generic solution).
     
  8. Neural Echo

    Neural Echo

    Joined:
    Jul 5, 2007
    Posts:
    83
    Is it possible to measure the length of the vertex you are colliding with and only engage the slide motion if the vertex is greater than a certain length?
     
  9. Brian-Kehrer

    Brian-Kehrer

    Joined:
    Nov 7, 2006
    Posts:
    411
    we solved this by calculating the actual slope angle, and slide direction, and figuring out the component gravity.
    It should look roughly like this I think
    Code (csharp):
    1.  
    2. if(groundSlopeAngle > 45){
    3. slideVal += groundSlopeDir*Time.deltaTime*gravity*Mathf.Sin(groundSlopeAngle*Mathf.Deg2Rad)
    4. }
    5. else{
    6. slideVal = slideVal*.95f;
    7. }
    8. motionDirection = inputMotion;
    9.  
    10. motionDirection += slideVal;
    11.  
    You can then add this to your normal target position the same way you add gravity.

    Over a small 'bump' if you run over it, your running speed will overwhelm the effects of sliding. However if you try to run up a hill, you will only make it so far before the cumulative effect of sliding overpowers it.

    Add some conditions to determine when you are sliding, and how it falls off.

    we solved this by calculating the actual slope angle, and slide direction, and figuring out the component gravity.
    It should look roughly like this I think
    Code (csharp):
    1.  
    2. if(groundSlopeAngle > 45){
    3. slideVal += groundSlopeDir*Time.deltaTime*gravity*Mathf.Sin(groundSlopeAngle*Mathf.Deg2Rad)
    4. }
    5. else{
    6. slideVal = slideVal*.95f;
    7. }
    8. motionDirection = inputMotion;
    9.  
    10. motionDirection += slideVal;
    11.  
    You can then add this to your normal target position the same way you add gravity.

    Over a small 'bump' if you run over it, your running speed will overwhelm the effects of sliding. However if you try to run up a hill, you will only make it so far before the cumulative effect of sliding overpowers it.

    Add some conditions to determine when you are sliding, and how it falls off.

    Here is how we got the angles needed
    Code (csharp):
    1.  
    2.  
    3.     void OnControllerColliderHit (ControllerColliderHit hit){
    4.         Vector3 temp = Vector3.Cross(hit.normal, Vector3.down);
    5.         groundSlopeDir = Vector3.Cross(temp, hit.normal);
    6.         groundSlopeAngle =  Vector3.Angle(hit.normal,Vector3.up);
    7.     }
    8.  
     
  10. Fishypants

    Fishypants

    Joined:
    Jan 25, 2009
    Posts:
    444
    Hey Brian, sorry for posting in an old post, but I am trying to get your example working, but I don't think I'm implementing it correctly . . .

    So im trying to get the function, "OnControllerColliderHit" working, but when I use the code, it gives me these errors:

    ';' expected. Insert a semicolon at the end.
    BCE0043: Unexpected token: )
    BCE0044: expecting :, found 'temp'.

    I'm in the process of learning unity, so certain things aren't as obvious to me yet as they should be, but could you or someone else explain to me the proper way to use this code?

    Should I add your code to a script and attach it to the object and it should just go? I'm a little confused.
     
  11. Fishypants

    Fishypants

    Joined:
    Jan 25, 2009
    Posts:
    444
    Wait, nevermind. I figured it out :D Thanks for posting the code! I had to tweak it a bit to work with my scene but all is well now. It works great!
     
  12. Brian-Kehrer

    Brian-Kehrer

    Joined:
    Nov 7, 2006
    Posts:
    411
    No problem. Look for that bit of code appearing in our upcoming iPhone game :).
     
  13. javiermorawski

    javiermorawski

    Joined:
    Feb 16, 2012
    Posts:
    2
    Hey Fishypants, I know that this post is WAAAAAAYY old by now, but I'm also trying to implement this, and I am getting the same error messages.
    Like you (at the time of your post) am relatively new to Unity javascript, and I have been cracking my brain on this.
    You wouldn't happen to remember what your fix was do you?
    Error: ';' expected. Insert a semicolon at the end.

    and its talking about the line:

    Vector3 temp = Vector3.Cross(hit.normal, Vector3.down);

    of code:

    Code (csharp):
    1. function OnControllerColliderHit (hit: ControllerColliderHit)
    2.     {
    3.     Vector3 temp = Vector3.Cross(hit.normal, Vector3.down);
    4.     groundSlopeDir = Vector3.Cross(temp, hit.normal);
    5.     groundSlopeAngle =  Vector3.Angle(hit.normal,Vector3.up);
    6.    
    7.     }
     
  14. javiermorawski

    javiermorawski

    Joined:
    Feb 16, 2012
    Posts:
    2
    Nevermind... Also figured it out
     
  15. RonHiler

    RonHiler

    Joined:
    Nov 3, 2011
    Posts:
    207
    Very cool! I thought I was the only one on the planet that preferred their braces have the same indentation as the code block they go with. Thank you for letting me know I'm not alone! :)