Search Unity

Need script for fixing Infinite Jumps | Mobile 2D

Discussion in 'Scripting' started by bitlysub2anf, May 31, 2020.

?

Why is coding in so many different languages?

Poll closed Jun 1, 2020.
  1. Duh! It's because we have to use different languages for different situations

    1 vote(s)
    100.0%
  2. No, they are in little variation

    0 vote(s)
    0.0%
  3. IDK

    0 vote(s)
    0.0%
  4. C# is the best

    0 vote(s)
    0.0%
  5. C++ is the best

    0 vote(s)
    0.0%
  6. Why are you asking?

    0 vote(s)
    0.0%
  7. Empty Response

    0 vote(s)
    0.0%
  1. bitlysub2anf

    bitlysub2anf

    Joined:
    May 8, 2020
    Posts:
    71
    Tags: IfGrounded | Infinite Jumps | for mobile | Android | iPhone | IOS | Fix | 2D

    Okay, so first I needed help with jump buttons for my android game. Now that got fixed, but of course, that would only make my player jump. Now, I watched a few tutorials for ifGrounded, but there were two problems:

    1. It was meant ony for PCs, no UI Buttons
    2. My Jump script is attached to my button, not my player
    3. I am not very good at scripting and making connections between scripts, I am still learning C# and Unity itself
    Now, what I need is a script (with it's meaning in simple words) for if grounded and I want to know where it gets attached to. I think, I have to link my jump button script for jumping to my player. So I'll need the jump script, so here it is (please do not mind the comments, I keep those for remembering what they do):
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.EventSystems;
    3.  
    4. public class btnbckupjmp : MonoBehaviour
    5. {
    6.  
    7.     private bool shouldJump = false;
    8.  
    9.     // Update is called once per frame
    10.     void Update()
    11.     {
    12.         //Find the player
    13.         var player = GameObject.FindGameObjectWithTag("Player");
    14.         //No player? exit out.
    15.         if (player == null)
    16.             return;
    17.         //Is the jump button currently being pressed?
    18.         if (shouldJump)
    19.         {
    20.             //Translate it upwards with time.
    21.             player.transform.Translate(new Vector3(0, Time.deltaTime * 5, 0));
    22.             //Make sure the Rigidbody is kinematic, or gravity will pull us down again
    23.             if (player.GetComponent<Rigidbody2D>().isKinematic == false)
    24.                 player.GetComponent<Rigidbody2D>().isKinematic = true;
    25.         }
    26.         //Not jumping anymore? reset the Rigidbody.
    27.         else
    28.             player.GetComponent<Rigidbody2D>().isKinematic = false;
    29.     }
    30.  
    31.     //When the button is being pressed down, this function is called.
    32.     public void ButtonPressedDown(BaseEventData e)
    33.     {
    34.         shouldJump = true;
    35.     }
    36.  
    37.     //When the button is released again, this function is called.
    38.     public void ButtonPressedUp(BaseEventData e)
    39.     {
    40.         shouldJump = false;
    41.     }
    42. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    Excellent, glad to hear it. Welcome! First lesson: don't post silly irrelevant polls if you wish us to take you seriously. The one above is pure noise.

    Alas this is not how this forum works. We're all writing our own games thank you.

    In this forum YOU write the script, you genuinely ATTEMPT the thing you want, and when you have a very specific problem, you isolate the part of the code causing you problems and post ONLY that code. There are youtube tutorials for virtually anything you want to do, so go work through two or three of them involved in jumping and see how easy it can be.

    Starting from the code above, you could learn a lot about how it works by inserting Debug.Log() statements here and there to display the state of various boolean variables as you play.

    You can do it. We're all rooting for you.
     
    bitlysub2anf and Yanne065 like this.
  3. bitlysub2anf

    bitlysub2anf

    Joined:
    May 8, 2020
    Posts:
    71
    Noted, sorry about that.

    Also, I check out more of those tutorials, try to mess with the code as much as possible and if I get any errors or confusions but still do not get any answers in other forums and the documentation, I'll let you know.
    AND... Thank you very much for helping me out ^0^
     
  4. bitlysub2anf

    bitlysub2anf

    Joined:
    May 8, 2020
    Posts:
    71
    Update: After some research, I came up with this script, but for some reason it does not work:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ExampleClass : MonoBehaviour
    6. {
    7.  
    8.     bool grounded = false;
    9.  
    10. void Update()
    11. {
    12.         var player = GameObject.FindGameObjectWithTag("Player");
    13.         if (player == null)
    14.             return;
    15.        if (Input.GetMouseButtonDown(0) && grounded)
    16.      {
    17.            GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 200f));
    18.      }
    19. }
    20.  
    21. void OnCollisionEnter2D(Collision2D col)
    22. {
    23.     if (col.gameObject.tag == "Ground")
    24.     {
    25.         grounded = true;
    26.     }
    27.  
    28.         Debug.Log("Contact Started");
    29. }
    30.  
    31. void OnCollisionExit2D(Collision2D col)
    32. {
    33.     if (col.gameObject.tag == "Ground")
    34.     {
    35.         grounded = false;
    36.     }
    37.  
    38.         Debug.Log("Contact Ended");
    39.  
    40.     }
    41. }
    I need make some measures to estimate what's causing the problem, but it has led me clueless. Also, there are no warnings or compile errors.
    Here are some more details:
    • Debug.Log did work until I added ifgetmousedown, now it does not even respond at all
    • It never jumped
    • I have all the tags set
    • The button does press but does not respond
    • This script is bricked (or at least what I think)
    • I think I may need to change the the entire script's structure
    • This script is attached to my jump button
    • This script has been combined from a script from a video (as shown) and the script above

    • I am completely lost and at this point, I do not even know what I am trying to do. Any hint (or solution for this error) would be appreciated
    Note: I did not get any errors in Visual Studio or Unity
    Also, I tried to change my script to this, but still no luck:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ExampleClass : MonoBehaviour
    6. {
    7.    
    8.     bool grounded = false;
    9.     public float speed = 10;
    10.  
    11. void Update()
    12. {
    13.         var player = GameObject.FindGameObjectWithTag("Player");
    14.         if (player == null)
    15.             return;
    16.        if (Input.GetMouseButtonDown(0) && grounded)
    17.      {
    18.             GetComponent<Rigidbody2D>().AddForce(Vector2.up * speed);
    19.         }
    20. }
    21.  
    22. void OnCollisionEnter2D(Collision2D col)
    23. {
    24.     if (col.gameObject.tag == "Ground")
    25.     {
    26.         grounded = true;
    27.     }
    28.  
    29.         Debug.Log("Contact Started");
    30. }
    31.  
    32. void OnCollisionExit2D(Collision2D col)
    33. {
    34.     if (col.gameObject.tag == "Ground")
    35.     {
    36.         grounded = false;
    37.     }
    38.  
    39.         Debug.Log("Contact Ended");
    40.  
    41.     }
    42. }
     
    Last edited: Jun 2, 2020
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    So the kind of Debug.Log() stuff I'm talking about is sooooper-simple like ultra-skeptical stuff. Here is the above Update function redone as if I was finding my own bug. Every one of the Debug.Log() statements I put in is me going. "Let's see if THIS fails!"

    Code (csharp):
    1. void Update()
    2. {
    3.         var player = GameObject.FindGameObjectWithTag("Player");
    4.         if (player == null)
    5.         {
    6.             Debug.Log(" No Player!");
    7.             return;
    8.         }
    9.         Debug.Log( "grounded is " + grounded);
    10.         if (Input.GetMouseButtonDown(0) && grounded)
    11.         {
    12.            Debug.Log( "Launch!");
    13.            GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 200f));
    14.         }
    15. }
    If you change that code and don't see any debugging, well, the script isn't running because we know SOMETHING should print.

    If you see it say no player, there's a problem with finding the player. By the way, you shouldn't have that in Update, but let's leave that detail alone for now.

    If grounded is reported false, we have another problem happening... perhaps you are already IN the ground when this starts, so you never get an Enter.

    Finally if you see "Launch!" and he still doesn't move, multiply the force by 10x, then 100x, etc.

    That's kinda how you have to approach this stuff otherwise you're really just wasting your own time. Bite the bullet, sprinkle Debug.Log() calls in there EVERYWHERE, and soon you start to get a picture of what is going on.
     
  6. bitlysub2anf

    bitlysub2anf

    Joined:
    May 8, 2020
    Posts:
    71
    Okay, since I was going into the root of the problem, I decided to go from scratch to one new command on the code. Here is the log:

    I first started with nothing but:
    Code (CSharp):
    1.     void Update()
    2.     {
    3.             if (Input.GetMouseButtonDown(0))
    4.         {
    5.             Debug.Log("Launch!");
    6.             GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 1000f)); //Initially started with 200f
    7.         }
    8.     }
    The result, of course was nothing, but Launch. I looked further (keeping in mind of your words) and found out that the problem was actually gravity (which was too high) and fixed that boom, but wait, I applied the script to the player itself. Okay, seems resonable. First step has been taken.

    Now, here's where the bug (I think Logical Bug) enters:
    I applied the same script to the button (after removing it from the player) and added:
    Code (CSharp):
    1.         var player = GameObject.FindGameObjectWithTag("Player");
    2.         if (player == null)
    3.         {
    4.             Debug.Log(" No Player!");
    5.             return;
    6.         }
    on top of the main code
    . Now, I am unsure how to fix it, but I do know what's it saying. Here is the console:
    Note: The player did not jump
    Annotation 2020-06-02 071314.png Please note that other Jump scripts are disabled and this message only appear when I click the button
    Also, it is trying to look for the Rigidbody2D in the button itself, however the same beginning is used in the script, it works no matter what (the raw Jump script at the very top). Also, my theory is that the way that the jump function works is with this piece of code (for more info go to raw script):
    player.transform.Translate(new Vector3(0, Time.deltaTime * 25, 0));

    So, I went up ahead and gave it a shot, and voilà, it worked ╰(‵□′)╯

    Now, I am further testing it, but would be posting a second part for this (because the debugging thing is taking a bit too long, and before peace out, I want to say that I came up with another script (not tested):
    Code (CSharp):
    1.  //All the above stuff
    2. bool grounded;
    3. //Also, a conflict arrived (in my head) that this script may not work due to bool grounded being on a certain value, so until further testing this is the initial script
    4.  
    5. void Update()
    6. {
    7.      if (grounded == true)
    8.      {
    9.          //The jump code goes here
    10.      }
    11. }
    12.  
    13. void OnCollisionEnter2D(Collision2D theCollision)
    14. {
    15.      if (theCollision.gameObject.tag == "Ground")
    16.      {
    17.          grounded = true;
    18.      }
    19. }
    20. //consider when character is jumping .. it will exit collision.
    21. void OnCollisionExit2D(Collision2D theCollision)
    22. {
    23.      if (theCollision.gameObject.tag == "Ground")
    24.      {
    25.          grounded = false;
    26.      }
    27. }
    I'll let you know on more updates soon (´・ω・`)





    Personal Messages:
    Hi there, thanks for helping me out. So far, we have done something that I could've done (alone) in 2 weeks or so, thanks a lot for your precious precious time :D
    Also, what about the update thing that I should not use?
    Is it because FixedUpdate updates more but Update does not do so, causing lower frames?
    I am taking a few hours off, so the second report will come a bit more later (like upto days)
    Phew that's a big report part 1
     
    Last edited: Jun 2, 2020
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    You have been VERY industrious. I love it. Keep going! Feel your brain expanding??

    As for the Update(), there are certain functions that are "heavier" than others. The
    GameObject.FindGameObjectWithTag()
    function is one of those. Probably not a problem if you only have one per frame (Update()), but have hundreds and you'll have a problem.

    NOW... instead of assigning what that function finds to a local
    player
    variable, instead make a member variable of type GameObject. Do NOT have the word
    var
    on any place you use it within a function, otherwise the local variable gets created and "hides" the member variable of the same name.

    BUT! That variable would be null, so we create a
    void Start()
    function that does your GameObject.FindGameObjectWithTag() and assigns the result to that member variable. Then the Update() only uses it, does not call GameObject.FindGameObjectWithTag() every frame.
     
  8. bitlysub2anf

    bitlysub2anf

    Joined:
    May 8, 2020
    Posts:
    71
    I have bad news, the charts are going down ╯︿╰
    Here's the report:

    So, I follwed your instructions and removed the var and made some other adjustments, but before that I tried it as it was simply just inserting the code. I didn't get any errors, but it never worked and I put a debug on this part of the code:
    Code (CSharp):
    1. void OnCollisionEnter2D(Collision2D theCollision)
    2. {
    3.      if (theCollision.gameObject.tag == "Ground")
    4.      {
    5.          grounded = true;
    6.      }
    7. }
    8. //consider when character is jumping .. it will exit collision.
    9. void OnCollisionExit2D(Collision2D theCollision)
    10. {
    11.      if (theCollision.gameObject.tag == "Ground")
    12.      {
    13.          grounded = false;
    14.      }
    both with and without the
    grounded = x
    statement. No luck. I also, faced some other difficulties for some other reasons relating to this. I left this piece of code and now made some changes (your instructions). Here's the result: Under testing [Estimated to fail by 37.5%]

    Yea, so the reason I had to send report 2 without that was because I remembered that there is Unity Learn and in there is a Platformer, a (better) replica of what I am making, and I remember using it and not flying off into the sky, which means that without doubt, there is a script which I need and can be used as (a confirmed and working) script. I then found out PlayerController, which of cource did not only contain the grounded function, but a load of others. So here's the same script with components that are not needed removed and some other changes (mentioned within the script). I also had to face some errors:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. namespace Platformer.Mechanics //Never seen this before
    6. {
    7.     public class PlayerController : MonoBehaviour //The mono was kinematic before
    8.     {
    9.         public float maxSpeed = 7;
    10.         public float jumpTakeOffSpeed = 7;
    11.  
    12.         public JumpState jumpState = JumpState.Grounded; //I think this is a part for the grounded function
    13.         private bool stopJump;
    14.         /*internal new*/ //Any idea what this does?
    15.         public Collider2D collider2d;
    16.         /*internal new*/
    17.         public bool controlEnabled = true;
    18.  
    19.         bool jump;
    20.         Vector2 move;
    21.  
    22.         public Bounds Bounds => collider2d.bounds; //Do I need this?
    23.  
    24.         void Awake()
    25.         {
    26.             collider2d = GetComponent<Collider2D>(); //What does this do? Is this a Box Collider?
    27.         }
    28. // I do not think that I need controls, I may need to merge pre-existing scripts
    29.         void Update()
    30.         {
    31.             if (controlEnabled)
    32.             {
    33.                 move.x = Input.GetAxis("Horizontal");
    34.                 if (jumpState == JumpState.Grounded && Input.GetButtonDown("Jump"))
    35.                     jumpState = JumpState.PrepareToJump;
    36.                 else if (Input.GetButtonUp("Jump"))
    37.                 {
    38.                     stopJump = true;
    39.                     Schedule<PlayerStopJump>().player = this;
    40.                 }
    41.             }
    42.             else
    43.             {
    44.                 move.x = 0;
    45.             }
    46.             UpdateJumpState();
    47.             base.Update();
    48.         }
    49.  
    50.         void UpdateJumpState()
    51.         {
    52.             jump = false;
    53.             switch (jumpState)
    54.             {
    55.                 case JumpState.PrepareToJump:
    56.                     jumpState = JumpState.Jumping;
    57.                     jump = true;
    58.                     stopJump = false;
    59.                     break;
    60.                 case JumpState.Jumping:
    61.                     if (!IsGrounded)
    62.                     {
    63.                         Schedule<PlayerJumped>().player = this;
    64.                         jumpState = JumpState.InFlight;
    65.                     }
    66.                     break;
    67.                 case JumpState.InFlight:
    68.                     if (IsGrounded)
    69.                     {
    70.                         Schedule<PlayerLanded>().player = this;
    71.                         jumpState = JumpState.Landed;
    72.                     }
    73.                     break;
    74.                 case JumpState.Landed:
    75.                     jumpState = JumpState.Grounded;
    76.                     break;
    77.             }
    78.         }
    79.  
    80.         protected override void ComputeVelocity() //I got this error with this line: error CS0115: 'PlayerController.ComputeVelocity()': no suitable method found to override and after removing protected override, I got errors relating from all the below code
    81.         {
    82.             if (jump && IsGrounded)
    83.             {
    84.                 velocity.y = jumpTakeOffSpeed * model.jumpModifier;
    85.                 jump = false;
    86.             }
    87.             else if (stopJump)
    88.             {
    89.                 stopJump = false;
    90.                 if (velocity.y > 0)
    91.                 {
    92.                     velocity.y = velocity.y * model.jumpDeceleration;
    93.                 }
    94.             }
    95.         }
    96.  
    97.         public enum JumpState
    98.         {
    99.             Grounded,
    100.             PrepareToJump,
    101.             Jumping,
    102.             InFlight,
    103.             Landed
    104.         }
    105.     }
    106. }
    This has been a bad update (≧口≦)



    Personal Messages:
    Yea, I'm despressed (not really, actually mad at myself)
    Sorry if I let you down, as I said earlier, I am totally new and all that I have learned is controls
    Any idea for my next move for this?
    What the conclusion for this report is:
    • Let me know how I am doing
    • Let me know what should I do
    • Let me know what AM I EVEN DOING
    • Let you know what have I done so far
    OMG, you have made games and I didn't even know about them. I'll try some of your games and rate them as soon as I get off unity and rate them at least 4.
     
  9. bitlysub2anf

    bitlysub2anf

    Joined:
    May 8, 2020
    Posts:
    71
    Um... Hello?