Search Unity

[Resolved] Variable Jump Heights with different gravity rotations

Discussion in '2D' started by Cornysam, Nov 16, 2019.

  1. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,465
    Here is my problem: I have edited my jump to be variable (like Mario) so if i tap the button the character jumps to a lower height than if you hold the jump button. No problem, got it working well. My issue is that I rotate the gravity at certain checkpoints and want to have this applied to the jump when the gravity is pushing down to the right (and eventually upside down).

    To me, the logic should be pretty much the same except switching from Y axis to the X. See my code below:

    Code (CSharp):
    1. [SerializeField]
    2.     private float fallMultiplier = 8.5f;
    3.  
    4.     [SerializeField]
    5.     private float lowJumpMultiplier = 12.5f;
    6.  
    7.     Rigidbody2D rb;
    8.     GravityRotationChecker gRC;
    9.  
    10.     private void Awake()
    11.     {
    12.         rb = GetComponent<Rigidbody2D>();
    13.         gRC = GetComponent<GravityRotationChecker>();
    14.     }
    15.    
    16.     // Update is called once per frame
    17.     void FixedUpdate () {
    18.         if(gRC.JumpDirectionToTheLeft)
    19.         {
    20.             VariableRotatedJump();
    21.         }
    22.         else
    23.         {
    24.             VariableJumpUpwards();
    25.         }
    26.  
    27.        
    28.     }
    29.  
    30.     //This function does not work as expected.
    31.     void VariableRotatedJump()
    32.     {
    33.         if (rb.velocity.x < .25f)
    34.         {
    35.             rb.gravityScale = fallMultiplier;
    36.             //Not jumping
    37.         }
    38.         else if (rb.velocity.x > .25f && !CrossPlatformInputManager.GetButton("Jump"))
    39.         {
    40.             rb.gravityScale = lowJumpMultiplier;
    41.             Debug.Log("LOW JUMP TO THE LEFT");
    42.             //Low Jump
    43.         }
    44.         else
    45.         {
    46.             rb.gravityScale = 6.5f;
    47.             //High Jump
    48.         }
    49.     }
    50.  
    51.     //This function below works perfectly.
    52.     void VariableJumpUpwards()
    53.     {
    54.         if (rb.velocity.y < 0.25f)
    55.         {
    56.             rb.gravityScale = fallMultiplier;
    57.             //Not jumping
    58.         }
    59.         else if (rb.velocity.y > 0.25f && !CrossPlatformInputManager.GetButton("Jump"))
    60.         {
    61.             rb.gravityScale = lowJumpMultiplier;
    62.             //Low jump
    63.         }
    64.         else
    65.         {
    66.             rb.gravityScale = 6.5f;
    67.             //High jump
    68.         }
    69.     }
    This is the script attached to the Player that will edit the regular jump code. Here is the regular jump code that I have expanded upon:

    Code (CSharp):
    1. public void DoJump()
    2.     {
    3.         if (rb.velocity.y <= .25 && rb.velocity.y >= -.25)
    4.         {
    5.             rb.AddForce(new Vector2(0, jumpForce), ForceMode2D.Impulse);
    6.         }
    7.     }
    8.     //function to make player jump after gravity has rotated
    9.     public void DoRotatedJump()
    10.     {
    11.         if(rb.velocity.x <= 0.25)
    12.         {
    13.             rb.AddForce(new Vector2(-jumpForce, 0), ForceMode2D.Impulse);
    14.         }
    15.     }
    16.     //function to make player jump after gravity is flipped upsidedown
    17.     public void DoUpsideDownJump()
    18.     {
    19.         if (rb.velocity.y <= .25)
    20.         {
    21.             rb.AddForce(new Vector2(0, -jumpForce), ForceMode2D.Impulse);
    22.         }
    23.     }
    I have no issues with my DoJump, DoRotatedJump or UpsideDown. They still work properly depending on the rotation but it is the other script (above) that doesnt want to play nice.

    I have tried adding in Debug.Logs to find the rb.velocity.y for the code that works and rb.velocity.x for the code that isnt working properly. There doesnt seem to be any real difference in the values. I have switched the < and > signs to see if that makes a difference since technically RotatedJump will move player in the -X direction first. I have tried increasing the .25f in the IF statements to 0, .1, .5, .75, 1.0 and even 10 with no real effect. I can occasionally (very very brief moment) to get the High Jump in the RotatedJump to call but it doesnt seem to affect the jump height distance. I have tried some other things but so many I cant exactly remember which ones.

    Any help is appreciated.
     
  2. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    Maybe you need to make your functions public on your top script and pass in a variable from the bottom script to it and return the information?
     
    Cornysam likes this.
  3. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,465
    I never thought of that, thank you for the idea! I am still confused as to why the VariableJump works in the normal rotation with the current code but the LeftJump doesnt. Regardless, I am definitely trying your suggestion out when i get home.
     
    MisterSkitz likes this.
  4. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,465
    After struggling with this more I believe (could be very wrong though) that passing a variable to it wouldnt matter. I am never calling the VariableJumps in the MovePlayer script where it checks for input on the touch buttons. So, I dont think it would do anything since there isnt really any info to grab from the variable jump functions. I could be totally wrong of course.

    Anyways, i'm still struggling with this so i am going to post more code to see if anyone can find out what is going on.
    Here is the full script for MovePlayer which checks for inputs and does most of the work. Just some context, the game i am making is a mobile where the device will be actually be rotated. Ambitious as hell but thought itd be challenging (it is).

    Code (CSharp):
    1. public class MovePlayer : MonoBehaviour
    2. {
    3.     [SerializeField] float dirX; //float that determines if player is moving left or right
    4.     [SerializeField] float dirY; //float that determines if player is moving left or right (when gravity is rotated)
    5.  
    6.     public float moveSpeed = 7f;
    7.  
    8.     [Range(1, 20)]
    9.     public float jumpForce = 950f;
    10.     public float slipFactor = .75f;
    11.  
    12.     Rigidbody2D rb;
    13.     Animator anim;
    14.  
    15.     [SerializeField] LayerMask whatIsGround; //sets up layermask for determining what is the ground (helps player jump)
    16.     //[SerializeField] LayerMask whatIsIce; //sets up layermask for determining what the ice is (stops player from jumping or moving)
    17.     [SerializeField] bool airControl = false; //whether or not the player can move in the air
    18.  
    19.     bool facingRight = true; //For determining which way the player is currently facing.
    20.     bool grounded = false; //bool to turn off or on depending if player is grounded or not
    21.    
    22.     Transform groundCheck; //A position marking where to check if the player is grounded.
    23.     Transform playerGraphics; //the transform of the player's graphics child
    24.  
    25.     float groundedRadius = .2f; //sets up the radius of the ground checker
    26.  
    27.     GravityRotationChecker gRC; //reference to the GravityRotationChecker script
    28.     ColliderManager colMgr;
    29.  
    30.     // Use this for initialization
    31.     void Start()
    32.     {
    33.         //set up rigidbody, animator, player's graphics, groundcheck and GravityRotationChecker script
    34.         rb = GetComponent<Rigidbody2D>();
    35.         anim = GetComponent<Animator>();
    36.         playerGraphics = transform.Find("Graphics");
    37.         groundCheck = transform.Find("GroundCheck");
    38.         gRC = GetComponent<GravityRotationChecker>();
    39.         colMgr = GetComponent<ColliderManager>();
    40.         //slipFriction = 1f;
    41.         //playerHealth = GetComponent<PlayerHealth>();
    42.        
    43.  
    44.         if (playerGraphics == null)
    45.         {//if there are no playerGraphics, log the error
    46.             Debug.LogError("There are no graphics object as a child of the player!");
    47.         }
    48.     }
    49.  
    50.     // Update is called once per frame
    51.     void Update()
    52.     {
    53.         //if the player is on the ground and airControl is true...
    54.         if (grounded || airControl)
    55.         {
    56.             if(gRC.JumpDirectionToTheLeft)
    57.             {
    58.                 anim.SetFloat("Speed", Mathf.Abs(dirY));
    59.             }
    60.             if (gRC.JumpDirectionUpsideDown)
    61.             {
    62.                 anim.SetFloat("Speed", Mathf.Abs(dirX));
    63.             }
    64.             else if (gRC.JumpDirectionToTheLeft == false && gRC.JumpDirectionUpsideDown ==false) //|| gRC.JumpDirectionUpsideDown)
    65.             {
    66.                 anim.SetFloat("Speed", Mathf.Abs(dirX));
    67.                 //set the parameter "Speed" in the animator to the absolute value of the dirX variable
    68.             }
    69.  
    70.             //set the dirX variable to the Horizontal input (for the touch buttons)
    71.             dirX = CrossPlatformInputManager.GetAxis("Horizontal");
    72.             dirY = CrossPlatformInputManager.GetAxis("Vertical");
    73.  
    74.             //if the player presses the jump button, is grounded, and the animator parameter bool is true...
    75.             if (CrossPlatformInputManager.GetButtonDown("Jump") && grounded && anim.GetBool("Ground"))
    76.             {
    77.                 DoJump(); //jump
    78.             }
    79.             else if (CrossPlatformInputManager.GetButtonDown("RotatedJump") && grounded && anim.GetBool("Ground"))
    80.             {
    81.                 DoRotatedJump(); //jump after gravity change
    82.             }
    83.  
    84.             else if (CrossPlatformInputManager.GetButtonDown("DoUpsideDownJump") && grounded && anim.GetBool("Ground"))
    85.             {
    86.                 DoUpsideDownJump(); //jump after gravity is flipped
    87.             }
    88.         }
    89.        
    90.         CheckForGraphicsFlip();
    91.     }
    92.  
    93.     private void FixedUpdate()
    94.     {
    95.  
    96.         //determines if player should move left/right or up/down
    97.         if (gRC.JumpDirectionToTheLeft)
    98.         {
    99.             MoveVertically();
    100.         }
    101.         if(gRC.JumpDirectionUpsideDown)
    102.         {
    103.             MoveHorizontally();
    104.         }
    105.         if(gRC.JumpDirectionUpsideDown ==false && gRC.JumpDirectionToTheLeft ==false)
    106.         {
    107.             MoveHorizontally();
    108.         }      
    109.  
    110.         //determines if player is touching the ground or not
    111.         grounded = Physics2D.OverlapCircle(groundCheck.position, groundedRadius, whatIsGround);
    112.         //onIce = Physics2D.OverlapCircle(groundCheck.position, groundedRadius, whatIsIce);
    113.         anim.SetBool("Ground", grounded); //sets the animator bool to equal the grounded bool
    114.     }
    115.  
    116.     //function to make player jump
    117.     public void DoJump()
    118.     {
    119.         if (rb.velocity.y <= .25 && rb.velocity.y >= -.25)
    120.         {
    121.             rb.AddForce(new Vector2(0, jumpForce), ForceMode2D.Impulse);
    122.         }
    123.     }
    124.     //function to make player jump after gravity has rotated
    125.     public void DoRotatedJump()
    126.     {
    127.         if(rb.velocity.x <= 0.25)
    128.         {
    129.             rb.AddForce(new Vector2(-jumpForce, 0), ForceMode2D.Impulse);
    130.         }
    131.     }
    132.     //function to make player jump after gravity is flipped upsidedown
    133.     public void DoUpsideDownJump()
    134.     {
    135.         if (rb.velocity.y <= .25)
    136.         {
    137.             rb.AddForce(new Vector2(0, -jumpForce), ForceMode2D.Impulse);
    138.         }
    139.     }
    140.  
    141.     void MoveHorizontally()
    142.     {
    143.         if(!colMgr.onIce)
    144.         {
    145.             //Moves the player left and right according to the buttons touched (left or right)
    146.             rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);
    147.         }
    148.         else
    149.         {
    150.             rb.AddForce(new Vector2(dirX * moveSpeed * slipFactor, rb.velocity.y));
    151.         }
    152.  
    153.     }
    154.  
    155.     void MoveVertically()
    156.     {
    157.         if (!colMgr.onIce)
    158.         {
    159.             rb.velocity = new Vector2(rb.velocity.x, dirY * moveSpeed);
    160.         }
    161.         else
    162.         {
    163.             rb.AddForce(new Vector2(rb.velocity.x, dirY * moveSpeed * slipFactor));
    164.         }
    165.        
    166.     }
    167.  
    168.     private void Flip()
    169.     {
    170.         //Switch the way the player is labelled as facing.
    171.         facingRight = !facingRight;
    172.  
    173.         //Multiply the player's x local scale by -1.
    174.         Vector3 theScale = playerGraphics.localScale;
    175.         theScale.x *= -1;
    176.         playerGraphics.localScale = theScale;
    177.     }
    178.  
    179.     void CheckForGraphicsFlip()
    180.     {
    181.         if (gRC.JumpDirectionToTheLeft)
    182.         {
    183.             if (dirY > 0 && !facingRight)
    184.                 Flip(); // ... flip the player's graphics.
    185.             //Otherwise if the input is moving the player left and the player is facing right...
    186.             else if (dirY < 0 && facingRight)
    187.                 Flip(); //... flip the player's graphics.
    188.         }
    189.  
    190.         if(gRC.JumpDirectionUpsideDown)
    191.         {
    192.             if (dirX < 0 && !facingRight)
    193.                 Flip();
    194.             else if (dirX > 0 && facingRight)
    195.                 Flip();
    196.         }
    197.  
    198.         else
    199.         {
    200.             if (dirX > 0 && !facingRight)
    201.                 Flip();
    202.             else if (dirX < 0 && facingRight)
    203.                 Flip();
    204.         }
    205.     }
    206. }
    Some images of the Player gameobject in the inspector:
    upload_2019-11-21_19-37-25.png
     
  5. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    Add a bool variable in your jump script isUpsideDown or something like that. Create another jump function, then when you set the isUpsideDown variable, determine which function gets called.
     
    Cornysam likes this.
  6. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,465
    I finally figured it out! So i sorta did what you suggested and used my already existing GravityRotationChecker bools to determine when to call which jump. It still didnt work but it basically made me refactor my code and I decided to break out my jump code from my MovePlayer script so it would be less confusing. After doing so, I still struggled and eventually realized a dumb blunder: where I was checking for the input from CrossPlatformInputManager, I was using "DoJump" instead of RotatedJump like in my regular rotation VariableJump.

    else if (rb.velocity.x > .25f && !CrossPlatformInputManager.GetButton("RotatedJump")) <----WRONG

    changed to: else if (rb.velocity.x < .25f && !CrossPlatformInputManager.GetButton("RotatedJump"))

    I couldnt highlight it since it was technically a string so I just never noticed it. After changing that, it still didnt work much to my dismay. So i started to go crazy and just changing whatever I could: mass x 100, gravityScale x 50, etc. Eventually I went back to one of the first things I tried (as mentioned in the original post) and flipped the rb.velocity.x from the if and the else if lines. Boom. Worked a charm. It doesnt really make sense to me still since when im not jumping, the X velocity should still be 0 (and it is when i logged it) but after a week and a half of bashing my skull into the monitor, I am okay with my result.

    MisterSkitz, I give you 100% credit and will name my next pet after you.
     
    MisterSkitz likes this.
  7. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    I look forward to seeing pictures of your Red nosed pit bull named Mr Skitz ;)

    Glad to hear ya got the code working, amigo! This was a tricky one!
     
  8. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,465
    Yeah, im not doing myself any favors with a rotating phone/tablet type of game. Literally makes even the movement and jumping hard to figure out. But its a fun project.
     
    MisterSkitz likes this.
  9. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    I love what you're doing here! Seems like a pretty trippy game! Mess with your head!
    Inbox me when you publish! I'll be happy to give it a try, amigo :)
     
    Cornysam likes this.