Home > Enterprise >  (Unity, 2D, C#) How can I make the player let go of a button before needing to press it again?
(Unity, 2D, C#) How can I make the player let go of a button before needing to press it again?

Time:07-02

This is a weirdly phrased question...and I don't know how to explain it well. I'm making a ledge hang mechanic for my game I'm making, you press either of the directions to get onto the ledge, but you also press the directions to get off of the ledge. This means while you're trying to get on the ledge, he instantly falls off. Making a fixed wait time also doesn't feel good...I'm thinking that it would set the axis to 0 until the button is let go, but the problem is that if it's 0, the button is let go. It's a conundrum I can't solve.

Here is the code that detects movements pressed on the left or right arrow keys.

mx = Input.GetAxisRaw("Horizontal");
//Detects if the left or right arrow keys are pressed, and turns it into a number.

Here's some of the code that detects movement while you're hanging There's already a problem...there's an "if hanging" statement right before that's supposed to restrict movement until you let go or jump, but since moving is supposed to ALSO get you out of the hanging, it makes this point moot. I could really just use different buttons, like restricting it to just the jump button or down key (since that uses a different variable), but I want to see if a solution is possible.

if (IsGrabbing == true)
    {
        rb.velocity = new Vector2(0f, 0f);
        rb.gravityScale = 0f;
// mx2 detects vertical movement. This is still a problem, if you're pressing down before you hang, it'll instantly hang instead of waiting for another press, but it's not as bad because you don't press down to hang on a ledge
        if (mx != 0 || mx2 < 0)
        {
//Just the code that makes you let go and unable to hang, this is reset when you land.
            IsGrabbing = false;
            anim.SetBool("IsHanging", false);
            redXSize = 10f;
            redYSize = 10f;
            greenXSize = 0f;
            greenYSize = 0f;
            rb.gravityScale = 5f;
        }

I've tried many things, a lot of "while" loops I've tried just crash the game. Does anyone know how to fix this issue? I'll provide all the code if needed.

Edit: With the help of the reply, I've found the solution! There needs to be a flag set like this, where by default it's false. However, it also only checks if it's false, and the else statement means it's true, not to mention the only way to set it to true bypasses that gate anyways. This gives the result needed! Also, while "while" loops seem to break it, adding a condition to every check to not do it while grabbing seemed to fix it. Thanks, everyone!

if (IsGrabbing == true)
    {
        if (mx != 0 && InitiateGrab == false)
        {
            InitiateGrab = false;
        }
        else
        {
            InitiateGrab = true;
        }
        rb.velocity = new Vector2(0f, 0f);
        rb.gravityScale = 0f;
        if (mx != 0 && InitiateGrab == true || mx2 < 0 && InitiateGrab == true)
        {
            IsGrabbing = false;
            InitiateGrab = false;
            anim.SetBool("IsHanging", false);
            anim.SetBool("IsRising", false);
            redXSize = 10f;
            redYSize = 10f;
            greenXSize = 0f;
            greenYSize = 0f;
            rb.gravityScale = 5f;
        }
    }

CodePudding user response:

Since you don't have the code. I can't exactly help you out with the specifics, but I still understand what you're asking and can still help you out. Here is the "sample" code that I'd use in your case:

bool isHanging = false;
void Update()
    {
        if (Input.GetKeyDown("space") && !isHanging)
        {
            isHanging = true;
            // Use ur code to hang onto the ledge.
        } else if (Input.GetKeyDown("space") && !isHanging)
        {
           isHanging = false;
           // Use ur code to get off the ledge.
        }
    }

bool CheckIfHanging()
{
   if(isHanging) { return false; }
   else return true;
}

Essentially, this causes a toggle effect where when you press the spacebar AND are close enough to the ledge, you set the bool to true, and you hang onto the ledge and went you want to get off it, you set the isHanging to false, and run your code to jump off the ledge. This does have the effect of making ur controls a toggle control however. If you're looking for a "press" control, where you hold onto a key to hold onto the ledge, and then let go when you press off, then maybe try this:

void Update()
    {
        if (Input.GetKeyDown("space"))
        {
            // Hang onto ledge
        } else if (Input.GetKeyUp("space"))
        {
            // Let go of ledge.
        }
    }

Hope I could help! (P.S. please put ur code in next time so that I can help you out more!)

CodePudding user response:

Quick update on my answer since u posted ur code. Maybe try changing ur movement code to something like this

bool isHanging = false;
int speed; [SerializeField]

void MoveCharacter()
{
if (isHanging) return;
else  mx = speed * Input.GetAxisRaw("Horizontal");
}

Essentially, this still allows you to move with your arrow keys, but will essentially stop your movement code if you're hanging. Also from ur previous comment, you said that you apparently can't use Input.GetKeyDown/Up for your left/right arrows? I'd recommend using KeyCode if that's the case, that should have the input for all btns in ur keyboard.

bool HangLedge()
{
if (!isHanging && Input.GetKeyDown(KeyCode.DownArrow)) return true;
else if (!isHanging && Input.GetKeyDown(KeyCode.DownArrow)) return false;
}
// Set ur ledge code and movement code to take this bool, and run the code when it's either false/true.

Hope I could clarify!

  • Related