Help with touch screen jump

Hello World. I’m about 95% done with a game I’m making. I used Brackey’s videos on YouTube to learn almost everything about scripting and game making. He explained moving the character perfectly but seemed to leave out everything else. Before I converted everything to Android, the game would have been ready to release, but I’m stuck on making my character jump on a touchscreen. All I want is to turn the “space” key into a touch screen command. No actual on screen button, just the entire right side of the screen as a jump button. It’s probably the simplest thing but I cannot find anything similar for the life of me. Any help would be awesome. Thank you

Here’s what I have so far:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public CharacterController2D controller;
    public Animator animator;

    public Joystick joystick;

    public float runSpeed = 40f;

    float horizontalMove = 0f;
    bool jump = false;

    // Update is called once per frame
    void Update()
    {
        if (joystick.Horizontal >= .1f)
        {
            horizontalMove = runSpeed;
        }
        else if (joystick.Horizontal <= -.1f)
        {
            horizontalMove = -runSpeed;
        } else
        {
            horizontalMove = 0f;
        }

        animator.SetFloat("Speed", Mathf.Abs(horizontalMove));

        if (Input.GetButtonDown("Jump"))
        {
            jump = true;
            animator.SetBool("isjumping", true);
        }
    }

    void FixedUpdate ()
    {
        // Move our character
        controller.Move(horizontalMove * Time.fixedDeltaTime, false, jump);
        jump = false;
    }



    public void OnLanding()
    {

        animator.SetBool("isjumping", false);
    }
}

Just check all touches and see if one goes down in the right hand rectangle.

You may want to also break apart these steps:

  • create variables to store all inputs (left/right/jump etc)

Each frame:

  • zero out all input in local variables
  • read input from keyboard/mouse when on PC or in editor
  • read input from touchscreen when on android / iOS
  • now separately act only upon the temporary variables

That way the move code and animation code doesn’t get hairy and complicated when you add a new input mechanism.

I have a package called proximity_buttons that shows how to do stuff like this. You don’t have to use the actual button classes I have in there, but you’re welcome to of course. The MicroTouch class abstracts mouse and touch screens into a single array, assigning a unique finger ID to the mouse, and the VAButton class gives you a virtual analog button which of course you can also just use for tapping. Tons of sample scenes using everything included.

proximity_buttons is presently hosted at these locations:

https://bitbucket.org/kurtdekker/proximity_buttons

https://github.com/kurtdekker/proximity_buttons

@Kurt-Dekker thank you for the reply. I check out some of the scenes from your proximity_buttons package. Very well done but unfortunately I’m such a newb that most of this is (literally) in another language to me. Im baffled that my game progressed this far and the entire thing is at a screeching halt just because I can’t make the character jump lol. Just looking at my code is there anything short and sweet I can put in a new C# script and assign it to a button? I know how to make a button and drag the character to it but there’s not option in my scripting to jump, just SetFloat. Thank you again bud!.

There could be… but I’m curious how that Joystick you’re using is working because AFAIK that’s not part of standard Unity. Is that code from the Brackey’s tutorial? If so, he does good stuff and there might be a button functionality in there too. Or perhaps if that Joystick came from another package, look in there to see if it has something button-like.

The trouble with using a regular Unity UI Button is I don’t think they will work if you are also touching the other side of the screen for the above joystick. The entire Unity UI system only works on one touch at a time, I believe. Perhaps someone else can correct me on that.

BUT… if you want a SUPER cheap and cheerful solution to just check for the onset of a touch somewhere in the right half of the screen, I just put this together, but I really can’t test it.

To try it, make a backup of your script, and then in your code above, replace line 34 (which currently reads as):

        if (Input.GetButtonDown("Jump"))

With this code:

        // lower right 3/4 of screen, roughly...
        Rect r = new Rect(
            Screen.width * 0.50f, Screen.height * 0.25f,
            Screen.width * 0.50f, Screen.height * 0.75f);
        bool KurtCheeseTouchJump = false;
        foreach( var touch in Input.touches)
        {
            if (touch.phase == TouchPhase.Began)
            {
                var pos = touch.position;
                pos.y = Screen.height - pos.y;  // must invert Y position

                if (r.Contains( pos))
                {
                    KurtCheeseTouchJump = true;
                }
            }
        }
        if (Input.GetButtonDown("Jump") || KurtCheeseTouchJump)

Copy paste that in (don’t retype it!), no guarantee it will work, but hey, only took me a minute, the code is pretty simple, and here’s what it does:

  • makes a screen rectangle to check touches against
  • iterates all the current touches presently onscreen
  • if a touch is a BEGAN kinda touch, then it checks if it is inside the rect
  • if it is a began and it is inside the rect, it sets KurtCheeseTouchJump to true
  • Finally it checks your previous “Jump” check as well as my KurtCheeseTouchJump and does your normal jump code (the jump = true, etc. block) if either condition is true

Hmm. I did like you said, deleted line 34 and replaced it with your code. The strange thing is that it didn’t do anything at all. In fact, it was like I never changed the code at all lol. The character still jumped with the space key, there were no Console errors, and apparently no differences. My character also depends on another movement script but this one never needed altering, even for the joystick. The joystick I used was from a pack simply called Joystick Pack. I used a floating joystick with an x-axis lock since there is no reason to use up or down in my game. This was all very plug and play with only a tiny alteration in the code I previously showed you… Here is the other code that my character uses.

using UnityEngine;
using UnityEngine.Events;

public class CharacterController2D : MonoBehaviour
{
    [SerializeField] private float m_JumpForce = 400f;                            // Amount of force added when the player jumps.
    [Range(0, 1)] [SerializeField] private float m_CrouchSpeed = .36f;            // Amount of maxSpeed applied to crouching movement. 1 = 100%
    [Range(0, .3f)] [SerializeField] private float m_MovementSmoothing = .05f;    // How much to smooth out the movement
    [SerializeField] private bool m_AirControl = false;                            // Whether or not a player can steer while jumping;
    [SerializeField] private LayerMask m_WhatIsGround;                            // A mask determining what is ground to the character
    [SerializeField] private Transform m_GroundCheck;                            // A position marking where to check if the player is grounded.
    [SerializeField] private Transform m_CeilingCheck;                            // A position marking where to check for ceilings
    [SerializeField] private Collider2D m_CrouchDisableCollider;                // A collider that will be disabled when crouching

    const float k_GroundedRadius = .2f; // Radius of the overlap circle to determine if grounded
    private bool m_Grounded;            // Whether or not the player is grounded.
    const float k_CeilingRadius = .2f; // Radius of the overlap circle to determine if the player can stand up
    private Rigidbody2D m_Rigidbody2D;
    private bool m_FacingRight = true;  // For determining which way the player is currently facing.
    private Vector3 m_Velocity = Vector3.zero;

    [Header("Events")]
    [Space]

    public UnityEvent OnLandEvent;

    [System.Serializable]
    public class BoolEvent : UnityEvent<bool> { }

    public BoolEvent OnCrouchEvent;
    private bool m_wasCrouching = false;

    private void Awake()
    {
        m_Rigidbody2D = GetComponent<Rigidbody2D>();

        if (OnLandEvent == null)
            OnLandEvent = new UnityEvent();

        if (OnCrouchEvent == null)
            OnCrouchEvent = new BoolEvent();
    }

    private void FixedUpdate()
    {
        bool wasGrounded = m_Grounded;
        m_Grounded = false;

        // The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
        // This can be done using layers instead but Sample Assets will not overwrite your project settings.
        Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
        for (int i = 0; i < colliders.Length; i++)
        {
            if (colliders[i].gameObject != gameObject)
            {
                m_Grounded = true;
                if (!wasGrounded)
                    OnLandEvent.Invoke();
            }
        }
    }


    public void Move(float move, bool crouch, bool jump)
    {
        // If crouching, check to see if the character can stand up
        if (!crouch)
        {
            // If the character has a ceiling preventing them from standing up, keep them crouching
            if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround))
            {
                crouch = true;
            }
        }

        //only control the player if grounded or airControl is turned on
        if (m_Grounded || m_AirControl)
        {

            // If crouching
            if (crouch)
            {
                if (!m_wasCrouching)
                {
                    m_wasCrouching = true;
                    OnCrouchEvent.Invoke(true);
                }

                // Reduce the speed by the crouchSpeed multiplier
                move *= m_CrouchSpeed;

                // Disable one of the colliders when crouching
                if (m_CrouchDisableCollider != null)
                    m_CrouchDisableCollider.enabled = false;
            } else
            {
                // Enable the collider when not crouching
                if (m_CrouchDisableCollider != null)
                    m_CrouchDisableCollider.enabled = true;

                if (m_wasCrouching)
                {
                    m_wasCrouching = false;
                    OnCrouchEvent.Invoke(false);
                }
            }

            // Move the character by finding the target velocity
            Vector3 targetVelocity = new Vector2(move * 10f, m_Rigidbody2D.velocity.y);
            // And then smoothing it out and applying it to the character
            m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref m_Velocity, m_MovementSmoothing);

            // If the input is moving the player right and the player is facing left...
            if (move > 0 && !m_FacingRight)
            {
                // ... flip the player.
                Flip();
            }
            // Otherwise if the input is moving the player left and the player is facing right...
            else if (move < 0 && m_FacingRight)
            {
                // ... flip the player.
                Flip();
            }
        }
        // If the player should jump...
        if (m_Grounded && jump)
        {
            // Add a vertical force to the player.
            m_Grounded = false;
            m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce));
        }
    }


    private void Flip()
    {
        // Switch the way the player is labelled as facing.
        m_FacingRight = !m_FacingRight;

        // Multiply the player's x local scale by -1.
        Vector3 theScale = transform.localScale;
        theScale.x *= -1;
        transform.localScale = theScale;
    }
}

And here is a picture of what’s going on so far. As you can see, I made a big “invisible” box on the right side of the screen. I don’t mind that being there since it’s not intrusive but there are no jump options under any linked scripts. Thanks again for your help. I desperately need it :\

6141234--670176--New Game.jpg

I’m sorry that cheap and cheerful code I put up didn’t work. You’re welcome to try and put Debug.Log() statements into it to ensure it is doing what you might expect but there’s not much more I can add from here.

Perhaps identify some tutorials that show you how to make a simple button, and work through those in another blank project, and once you get it working, bring the required stuff over to your game. That’s how I would approach it.

I agree. I definitely need to RTFM. Thank you so much for your help. This is a huge learning experience and I’m sure if I figure it out it’ll be really gratifying. You’ve been a huge help @Kurt-Dekker .

1 Like

Correction: WHEN you figure it out it’ll be really gratifying. Gotta think positive, never give up. Who knows, you might even find a bug in my code that only comes up in your setup, such that the code works in my setup but not yours. Stick with it man, you’ll be jumping.

I’m new to using Unity but I know how to get the touch screen to work. I don’t know how to make it work only on the right side of the screen but this code should work if you touch any part of the screen:

Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began

If you put that where your input for jumping should be, then it should work.

Sorry if you only can have it on the right side of the screen.

touch[0].pos holds where the first touch is, so

if(touch[0].pos.x > Screen.width * 0.5f) {
// on right side of screen
}

Untested, but should be it, or at least close…