0
\$\begingroup\$

I want to make my button do stuff when the player holds it. In this case, I want to make a grab function: when the button is down the character can grab objects, but if the button is up they do not grab it.

I already have the function using the Standard Assets CrossPlatformInput.

Here is how I have configured my button so far:

Inspector screenshot showing ButtonHandler script

Here is my script:

void Update()
{

    Physics2D.queriesStartInColliders = false;
    RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.right * transform.localScale.x, distance, boxMask);

    if (PushKey())
    {
        isGrab = !isGrab;

        if (hit.collider != null && hit.collider.gameObject.tag == "Box" && isGrab)
        {
            box = hit.collider.gameObject;
            box.GetComponent<FixedJoint2D>().connectedBody = this.GetComponent<Rigidbody2D>();
            box.GetComponent<FixedJoint2D>().enabled = true;
            box.GetComponent<Rigidbody2D>().gravityScale = 1;
            box.GetComponent<Rigidbody2D>().mass = 1;

        }
        else if (!isGrab)
        {
            box.GetComponent<FixedJoint2D>().enabled = false;
            box.GetComponent<Rigidbody2D>().gravityScale = 6;
            box.GetComponent<Rigidbody2D>().mass = 6;
        }
    }
}

public bool PushKey()
{
    return CrossPlatformInputManager.GetButtonDown("E");
}

With this function, the first tap on the button means "grab activated" and the second tap means "grab deactivated", like a toggle. Instead, I want the grab to be active as long as the button is held.

\$\endgroup\$
1
  • \$\begingroup\$ you might not want to call isGrab = !isGrab; on update with just the keypress state as check condition. \$\endgroup\$
    – Zibelas
    Commented Apr 4, 2021 at 17:25

1 Answer 1

1
\$\begingroup\$

First, change your event trigger. Right now you have both "Set Down State" and "Set Up State" called from the "Pointer Down" event.

You want to remove "Set Up State" from this event. Add a second event that listens for "Pointer Up" and attach your "Set Up State" to that one instead.

Then you want to change your code to check GetButton() (which returns true if the button is currently held), not GetButtonDown() (which returns true only the first frame that a button is pressed, and false for subsequent hold frames)

Something like this:

void Update()
{        
    if (CrossPlatformInputManager.GetButton("E"))
    {
        if (box == null) {
            TryGrab();
        }
    }
    else if (box != null) {
        Drop();
    }
}

void TryGrab() {
    Physics2D.queriesStartInColliders = false;
    RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.right * transform.localScale.x, distance, boxMask);

    // Use CompareTag, not .tag ==
    if (hit.collider != null && hit.collider.gameObject.CompareTag("Box"))
    {
        box = hit.collider.gameObject;
        var body = hit.rigidbody;
        var joint = box.GetComponent<FixedJoint2D>();

        joint.connectedBody = GetComponent<Rigidbody2D>();
        joint.enabled = true;
        body.gravityScale = 1;
        body.mass = 1;
    }
}

void Drop() {
    box.GetComponent<FixedJoint2D>().enabled = false;

    var body = box.GetComponent<Rigidbody2D>();
    body.gravityScale = 6;
    body.mass = 6;

    box = null;
}

As an aside, I'd also recommend naming your virtual button "Grab" not "E" - you might one day want to map it to a different control than "E", or give the player options to remap the control, so hard-coding a specific letter can cause trouble in the future.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .