How to keep my player moving as long as the button is held down

Viewed 28

I am trying to make a sort of momentum based platformer where you cant change direction or move in the air as a mobile game,

I am not the best at C# so forgive me if this is a stupid question,

I am using buttons from the canvas as my input, and I want my player to keep moving as long as the buttons are held down but I seem to have to keep tapping to make the player to move

enter code here using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class playerController : MonoBehaviour
{
private float moveSpeed;
private float jumpSpeed;
public bool onGround = true;

private Rigidbody2D playerRb;



// Start is called before the first frame update
void Start()
{
    moveSpeed = 100;
    jumpSpeed = 3;


    playerRb = GetComponent<Rigidbody2D>();
}

// Update is called once per frame
void Update()
{
    
}

void onCollisionEnter(Collision collision)
{
    if (collision.gameObject.tag == "Level")
    {
        onGround = true;
    }
} 

public void MoveLeft()
{

    if (onGround)
    {
        playerRb.AddForce(new Vector2(-moveSpeed, 0), ForceMode2D.Force);
    }
}

public void MoveRight()
{
    if (onGround)
    {
        playerRb.AddForce(new Vector2(moveSpeed, 0), ForceMode2D.Force);
    }
}

}

as you can see I have created 2 different functions for my button to activate when they are clicked

Is there anyway that I can make it so these function will keep going as long as the button is pressed down?

2 Answers

You will need some custom button that can actually do that.

E.g. something like

[RequireComponent(typeof (Button))]
public class ContinuousButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
    [SerializeField] private Button button;

    private Coroutine coroutine;

    private void Awake ()
    {
        Reset();
    }

    private void OnValidate()
    {
        Reset();
    }

    private void Reset ()
    {
        if(!button) button = GetComponent<Button>();
    }

    private void OnPointerEnter(PointerEventData pointerEventData)
    {
        // Not really doing anything but required for OnPointerExit to work
    }

    private void OnPointerExit(PointerEventData pointerEventData)
    {
        if(coroutine == null) return;

        // cancel the routine if pointer leaves button
        StopCoroutine (coroutine);
    }

    public void OnPointerDown(PointerEventData pointerEventData)
    {
        // optionally only take left mouse button and ignore the rest
        if(pointerEventData.button != PointerEventData.InputButton.Left) return;

        // Start a new continuous routine which will simulate a click each frame
        coroutine = StartCoroutine(WhilePressed(pointerEventData));
    }

    private void OnPointerUp(PointerEventData pointerEventData)
    {
        if(coroutine == null) return;

        // cancel the routine when letting go of the button
        StopCoroutine(coroutine);
    }

    private IEnumerator WhilePressed (PointerEventData eventData)
    {
        // This is fine in a Coroutine as long as you yield inside 
        while(true)
        {
            button.OnPointerClick(eventData);

            // Tells Unity to "pause" the execution here
            // render this frame and continue from here
            // in the next frame 
            yield return null;
        }
    }
}

Simply attach this to the same GameObject as the Button component and it should convert it into a continuous (hold down) button which basically calls onClick listeners every frame.

you need to set velocity of rigidbody when you get your button down and when you get your finger up set velocity to zero. It is a pretty simple implementation. I would also recommend to check how it is done in CorgiEngine for example.

Related