Search Unity

2D Platformer: Player can't ascend slopes

Discussion in '2D' started by JuiceBox, Aug 5, 2015.

  1. JuiceBox

    JuiceBox

    Joined:
    Jan 24, 2015
    Posts:
    41
    Alright, let me get some basics out of the way. I'm making a 2D platformer game (or sidescroller, as some call them) The player's hitbox is made out of a circle collider around his feet, and a box collider around the rest. Here, let me link a screenshot. (All the extra collision boxes are just triggers, so ignore them.)
    Another thing, I'm using Ferr2D. That shouldn't matter much, since it just generates polygon colliders. My player's horizontal movement is based on editing it's rigidbody's velocity. I'm guessing that's where the problem lies... Only problem is that using a Rigidbody2D.AddForce method doesn't work well either, since the player just goes a little bit up the slope and then slips down. Also, AddForce gives the player unwanted acceleration. So what can I do to fix this? Before I go, here's the player's movement script. If you decide to reply to this post, then thanks in advanced!

    Make sure to mostly pay attention to everything in the FixedUpdate function, since that's where most of the player's movement code lies. Really, you'd just want to look at everything under the "//Walking" comment.

    Code (JavaScript):
    1.  
    2. var moveSpeed : float;
    3. var jumpPower : float;
    4. var doubleJumpPower : float;
    5. var isGrounded : boolean;
    6. var isTouching : boolean;
    7. var respawning : boolean;
    8. var isPunching : boolean;
    9. var isAttacking : boolean;
    10.  
    11. var visible : boolean;
    12. var isPaused : boolean;
    13.  
    14. private var jumpHeight : float;
    15. private var jumping : boolean;
    16. private var facingRight : boolean;
    17. private var body : Rigidbody2D;
    18. private var oScale;
    19. private var spaceHeld : boolean;
    20. private var anim : Animator;
    21. private var isTouchingRight : int;
    22. private var jumpCount : int = 2;
    23. private var wentThrough : boolean;
    24. private var punchHeld : boolean;
    25.  
    26. private var horiIn : float;
    27. private var verIn : float;
    28. private var button1In : float;
    29. private var button2In : float;
    30. private var button3In : float;
    31.  
    32. function Start(){
    33.     body = GetComponent(Rigidbody2D);
    34.     oScale = transform.localScale.x;
    35.  
    36.     anim = GetComponent("Animator");
    37.  
    38. }
    39.  
    40.  
    41. //Movement
    42. function FixedUpdate(){
    43. if((anim.GetBool("isDead") == false)&&(isPaused == false)){
    44.  
    45.     //New Jumping
    46.     if((button1In == 1)&&(isGrounded)&&(!spaceHeld)&&(respawning == false)&&(!isPunching)){
    47.         body.AddForce(new Vector2(0,jumpPower),ForceMode2D.Impulse);
    48.     }
    49.     //DoubleJump
    50.     if((button1In == 1)&&(jumpCount > 0)&&(!isGrounded)&&(!spaceHeld)&&(respawning == false)&&(!isPunching)){
    51.         body.velocity.y=0;
    52.         body.AddForce(new Vector2(0,doubleJumpPower),ForceMode2D.Impulse);
    53.         jumpCount -= 1;
    54.     }
    55.  
    56.     if(isGrounded){
    57.         jumpCount = 2;
    58.         GameObject.Find("wallCheck").GetComponent(WallDetection).inAir = true;
    59.     }
    60.  
    61.     if((spaceHeld == false)&&(jumpCount > 0)&&(button1In == 1)&&(!isPunching)){
    62.         jumpCount -= 1;
    63.     }
    64.  
    65.     if(button1In == 1){
    66.         spaceHeld = true;
    67.     }else{
    68.         spaceHeld = false;
    69.     }
    70.  
    71.     //Checking if touching a wall
    72.     if(isTouching){
    73.  
    74.         if(facingRight){
    75.             isTouchingRight = 1;
    76.         }else{
    77.             isTouchingRight = -1;
    78.         }
    79.  
    80.     }else{isTouchingRight = 0;}
    81.  
    82.     //Walking
    83.     if((horiIn == 1)&&(isTouchingRight != 1)&&(respawning == false)&&(!isPunching)){
    84.         facingRight = true;
    85.         Flip();
    86.         maxSpeed = moveSpeed;
    87.     }
    88.     if((horiIn == -1)&&(isTouchingRight != -1)&&(respawning == false)&&(!isPunching)){
    89.         facingRight = false;
    90.         Flip();
    91.         wasD = false;
    92.         maxSpeed = -moveSpeed;
    93.     }
    94.  
    95.     body.velocity.x = maxSpeed;
    96.  
    97.     //body.AddForce(new Vector2(maxSpeed,0));
    98.  
    99.  
    100.  
    101. }
    102. }
    103.  
    104. function Update(){
    105.     //Setting my visible
    106.     visible = GetComponent(Renderer).isVisible;
    107.  
    108.     //Main Animations
    109.     if(((horiIn == -1)||(horiIn == 1))&&(isGrounded == true)&&(respawning == false)&&(!isPunching)&&(!isPaused)){
    110.         anim.SetInteger("Action",1);
    111.     }else if((body.velocity.y > 0)&&(isGrounded == false)&&(respawning == false)&&(!isPunching)&&(!isPaused)){
    112.         anim.SetInteger("Action",2);
    113.         GameObject.Find("wallCheck").GetComponent(WallDetection).inAir = true;
    114.     }else if((body.velocity.y < 0)&&(isGrounded == false)&&(respawning == false)&&(!isPunching)&&(!isPaused)){
    115.         anim.SetInteger("Action",4);
    116.         GameObject.Find("wallCheck").GetComponent(WallDetection).inAir = true;
    117.     }else if((horiIn == 0)&&(isGrounded == true)&&(respawning == false)&&(!isPunching)&&(!isPaused)){
    118.         anim.SetInteger("Action",0);
    119.     }else if((respawning == false)&&(!isPunching)){
    120.         anim.SetInteger("Action",0);
    121.     }
    122.     //Other Animations
    123.     if(respawning == true){
    124.             anim.SetInteger("Action",3);
    125.             if(isPunching){
    126.                 isPunching = false;
    127.                 anim.SetInteger("Action",3);
    128.                 wentThrough = false;
    129.                 isAttacking = false;
    130.             }
    131.         }
    132.  
    133.         //Punching
    134.         if((respawning == false)&&(isPaused == false)){
    135.             if((isGrounded)&&(isPunching == false)&&(button3In == 1)&&(punchHeld == false)){
    136.                 anim.SetInteger("Action",5);
    137.                 isPunching = true;
    138.             }
    139.             if((anim.GetCurrentAnimatorStateInfo(0).IsName("pPunching"))&&(isPunching)&&(wentThrough == false)){
    140.                 wentThrough = true;
    141.             }
    142.             if((anim.GetCurrentAnimatorStateInfo(0).IsName("pAttack"))&&(isPunching)){
    143.                 isAttacking = true;
    144.             }
    145.             if((anim.GetCurrentAnimatorStateInfo(0).IsName("pStanding"))&&(isPunching)&&(wentThrough == true)){
    146.                 isPunching = false;
    147.                 anim.SetInteger("Action",0);
    148.                 wentThrough = false;
    149.                 isAttacking = false;
    150.             }
    151.             //Making sure the player isn't respawning
    152.             if((anim.GetCurrentAnimatorStateInfo(0).IsName("pRespawn"))&&(isPunching)){
    153.                 isPunching = false;
    154.                 anim.SetInteger("Action",3);
    155.                 wentThrough = false;
    156.                 isAttacking = false;
    157.             }
    158.  
    159.             if(button3In == 1){
    160.                 punchHeld = true;
    161.             }else{
    162.                 punchHeld = false;
    163.             }
    164.         }
    165.     //Setting Inputs
    166.     horiIn = Input.GetAxis("Horizontal");
    167.     vertIn = Input.GetAxis("Vertical");
    168.     button1In = Input.GetAxis("Fire1");
    169.     button2In = Input.GetAxis("Fire2");
    170.     button3In = Input.GetAxis("Fire3");
    171.  
    172.  
    173. }
    174.  
    175.  
    176.  
    177. function Flip()
    178. {
    179.  
    180.     if(facingRight)
    181.         transform.localScale.x = oScale;
    182.     if(!facingRight)
    183.         transform.localScale.x = -oScale;
    184. }
    185.  
    186. function OnTriggerEnter2D(other : Collider2D){
    187.  
    188.     //Getting Crushed
    189.     if((other.tag == "Block")&&(transform.position.y < other.transform.position.y)){
    190.         if((other.GetComponent(Crate).canRight == true)&&(transform.position.x > other.transform.position.x)){
    191.             transform.position.x = other.transform.position.x + 1;
    192.         }else if((other.GetComponent(Crate).canLeft == true)&&(transform.position.x < other.transform.position.x)){
    193.             transform.position.x = other.transform.position.x - 1;
    194.         }else if(other.GetComponent(Crate).canRight == true){
    195.             transform.position.x = other.transform.position.x + 1;
    196.         }else if(other.GetComponent(Crate).canLeft == true){
    197.             transform.position.x = other.transform.position.x - 1;
    198.         }
    199.     }
    200. }
    201.  
     
  2. tedthebug

    tedthebug

    Joined:
    May 6, 2015
    Posts:
    2,570
    Have you thought about using the character controller instead? That lets you enter the slope angle that it can ascend
     
    theANMATOR2b likes this.
  3. JuiceBox

    JuiceBox

    Joined:
    Jan 24, 2015
    Posts:
    41
    I like to keep all my code custom, and have no real idea how to use a character controller. (Or even what one is, for that matter..)
     
  4. tedthebug

    tedthebug

    Joined:
    May 6, 2015
    Posts:
    2,570
    In physics you add the character controller instead of the rigidbody & you can still use your standard movement scripts that you write. It has premapped keys so you can just call input horizontal etc instead of specific keys, has jump built in, Gravity etc. maybe try adding one & just u tick the rigid body & see how it goes?
     
  5. JuiceBox

    JuiceBox

    Joined:
    Jan 24, 2015
    Posts:
    41
    Alright, thanks for the tip! I'll try that tomorrow,
     
  6. JuiceBox

    JuiceBox

    Joined:
    Jan 24, 2015
    Posts:
    41
    I can't seem to add a character controller due to all of the player's 2D colliders
     
  7. tedthebug

    tedthebug

    Joined:
    May 6, 2015
    Posts:
    2,570
    Is it difficult to turn the extra colliders off just to see if the controller works the way you want? It might be easier to then add them back via a childed empty game object.

    What is the wasD bool doing? You set it in one of the walking bits but not the other.
     
  8. JuiceBox

    JuiceBox

    Joined:
    Jan 24, 2015
    Posts:
    41
    I think that has stuff to do with animation, I actually just deleted it a second ago.
    I think I fixed the problem, though. I added some objects that checked whether or not the player is on a slope, done with 2 colliders. If the player is on a slope, he will automatically rotate 25 degrees on the Z axis. This seems to have fixed the problem pretty well, although it looks weird at times. But thanks for your help, anyways ^)^


    The Colliders that check for a slope, if the bottom one is inside of something while the top one isn't, it believes there is a slope present.


    On a slope
     
    tedthebug likes this.