简体   繁体   中英

What's the equivalent of GetKey in the new unity input system?

There's Started, Performed and Cancelled, but what if I want to detect if I'm holding down the button on a Gamepad. So basically, how do i rewrite this to a gamepad with the new input system.

private void Jump()
    {
        if (isTouchingGround == true && Input.GetKeyDown(KeyCode.Space))
        {
            isJumping = true;
            jumpTimeCounter = jumpTime;
            myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, 1 * jumpSpeed);
        }

        if (Input.GetKey(KeyCode.Space) && isJumping == true)
        {
            if (jumpTimeCounter > 0)
            {
                myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, 1 * jumpSpeed);
                jumpTimeCounter -= Time.deltaTime;
            }
            else
            {
                isJumping = false;
            }
        }
        if (Input.GetKeyUp(KeyCode.Space))
        {
            isJumping = false;
        }
    }

There is no equivalent! You have to Bind all Inputs to events and then process the inputs in the methods you assign to these events. This is because the new input system does not directly use Keys to make it work on multiple devices (keyboard, controller, phone, ...) without adding more code

See here .

The new input system exposes a Gamepad object with buttons each button is a ButtonControl that exposes accessors for the button state:

Input.GetKeyDown(KeyCode.JoystickButton2) ~= Gamepad.current.buttonWest.wasPressedThisFrame

Input.GetKey(KeyCode.JoystickButton2)     ~= Gamepad.current.buttonWest.isPressed

Input.GetKeyUp(KeyCode.JoystickButton2)   ~= Gamepad.current.buttonWest.wasReleasedThisFrame

Or if you want keyboard use Keyboard .

That lets you circumvent the new input system's configuration and hardcode your control scheme.


However, for supporting multiple input devices, you'd create a control scheme and use accessors on it:

Input.GetButton("fire")     ~= m_Controls.fire.ReadValue<bool>()

Input.GetButtonUp("fire")   ~= m_Controls.fire.triggered
Input.GetButtonDown("fire") ~= m_Controls.fire.triggered

triggered doesn't work quite like Input.GetButtonUp/Down. You'd configure the "fire" input for when during a press it should fire. You can set an input in your control scheme to be a Tap or SlowTap (ugh) and if it's a Tap, then triggered happens if it was released within the threshold time whereas SlowTaps are triggered if it's held for the threshold time.

You can also check which phase of press the input is in:

m_Controls.fire.phase == InputActionPhase.Started

If you go for this control scheme setup, see also this post about bad defaults .

I'd rewrite your code something like this (untested) and configure "jump" as a SlowTap with immediate activation:

void Jump()
{
    // maybe need to clear isJumping if isTouchingGround?
    if (isJumping)
    {
        if (m_Controls.gameplay.jump.ReadValue<bool>() && jumpTimeCounter > 0)
        {
            myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, 1 * jumpSpeed);
            jumpTimeCounter -= Time.deltaTime;
        }
        else
        {
            isJumping = false;
        }
    }
    // Use triggered to avoid jumping again when we hold button on landing
    else if (isTouchingGround && m_Controls.gameplay.jump.triggered)
    {
        isJumping = true;
        jumpTimeCounter = jumpTime;
        myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, 1 * jumpSpeed);
    }
}

(But I'm not particularly advanced with the new input system.)

I'd recommend playing around with the simple demo sample that can be imported from the package window. See how the different ways of using the system work.

#if !ENABLE_LEGACY_INPUT_MANAGER
        static Dictionary<KeyCode, Key> lookup = new Dictionary<KeyCode, Key>();
#endif

        bool GetKeyDown(KeyCode key)
        {
#if ENABLE_LEGACY_INPUT_MANAGER
            return Input.GetKeyDown(key);
#else
            if (lookup == null)
            {
                lookup = new Dictionary<KeyCode, Key>();
                foreach (KeyCode keyCode in Enum.GetValues(typeof(KeyCode)))
                {
                    var textVersion = keyCode.ToString();
                    if (Enum.TryParse<Key>(textVersion, true, out var value))
                        lookup[keyCode] = value;
                }
                lookup[KeyCode.Return] = Key.Enter;
            }
 
            return Keyboard.current[lookup[key]].wasPressedThisFrame;
#endif
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM