Search Unity

GetKey is too fast.

Discussion in 'Scripting' started by Philtho, Jan 12, 2014.

  1. Philtho

    Philtho

    Joined:
    Dec 18, 2013
    Posts:
    16
    I'm having a tough time trying to make this work.

    I have a top down game where you use the numpad to move the guy around the screen tile to tile.

    Initially I used GetKeyDown, and that worked great if you just wanted to hit the key a million times to walk down that corridor.

    So I tried GetKey which repeats, but it's way too fast. Just tapping numpad 6 makes the guy move about 5 squares to the right with the slightest touch. I'd like the key repeat to mimmick the system key repeat if possible. Is this possible?

    My movement code is basically like this in C#:

    void Update () {

    //
    // Move Right
    //
    if (Input.GetKey("[6]"){
    stuff
    }
    }

    How can I slow the key repeat down, but not limit it to a single key?
     
  2. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    can you post the movement code; are you multiplying with deltaTime?
     
  3. MeowMixEater

    MeowMixEater

    Joined:
    Dec 23, 2013
    Posts:
    18
    To directly answer the question you could do something this

    bool foo;

    if(Input.GetKey("[6]") foo == true){
    foo = !foo;
    //Stuff
    }
    Else if (foo == false){
    foo == !foo;
    }



    ^^ that would cut the amount of times your code is executed in half similarly you could iterate an int and reset to 0 each time the code executes if you need to be able to slow it down more than half.

    There is likely a better way to do what you are looking for though than slowing down the execution of Input.GetKey.
     
    Last edited: Jan 12, 2014
    tenzolinho likes this.
  4. Philtho

    Philtho

    Joined:
    Dec 18, 2013
    Posts:
    16
    I am just translating a sprite from one point to another. Think of it as a roguelike. Every 64 pixels per move. You can hold down the 6 key and the guy runs down the hall as fast as your system has its key repeat set at. With Unity, it updates every frame using Update() so it's much too fast.

    I'm not sure setting a variable or doing a loop would help, it would be different for every machine then. I was hoping there was something built into unity that would just set it to system, or maybe a way to define input.getkey rate. Maybe an Update method that fires every 1/25th of a second?
     
  5. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    set up a repeating timer, something like
    Code (csharp):
    1.  
    2. float lastStep, timeBetweenSteps = 0.5f;
    3.  
    4. if(getkey...){
    5.   if(Time.time - lastStep > timeBetweenSteps){
    6.     lastStep = Time.time;
    7.     //Do step
    8.   }
    9. }
    10.  
    will execute the step every 0.5 seconds
     
    MWMing, Zyon7, KarlManning and 7 others like this.
  6. unitylover

    unitylover

    Joined:
    Jul 6, 2013
    Posts:
    346
    Here's some sample code to get you started. Basically you want to keep track of the amount of time that has passed since the last frame, add it to a variable that keeps track of total time and then if the total time passed is greater than or equal to the customizable key delay then act accordingly. I hope this helps.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class KeyTest : MonoBehaviour {
    6.  
    7.     public float keyDelay = 1f;  // 1 second
    8.     private float timePassed = 0f;
    9.    
    10.     // Update is called once per frame
    11.     void Update () {
    12.         timePassed += Time.deltaTime;
    13.  
    14.         if (Input.GetKey(KeyCode.Space)  timePassed >= keyDelay) {
    15.             // do stuff
    16.             timePassed = 0f;
    17.         }
    18.     }
    19. }
    20.  
     
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Changing input rate is not what you want. If this is some sort of grid movement, then you simply have movement continue as long as the key is held down, and stop otherwise. See demo here and code here.

    --Eric
     
  8. Philtho

    Philtho

    Joined:
    Dec 18, 2013
    Posts:
    16
    Thanks for the suggestions! Checking them out now.

    It appears the timer suggestions seem to have a lower limit of around 0.5f .. if I change it to 0.25f or even 0.002f the delay is still .5 seconds. This is for both examples.

    Eric5h5, your example is better, but it is not precise. It is like the input is being buffered. In the demo, try and stop precisely at a predetermined point. More often than not, you will overshoot.

    Edit:

    The timer methods work, I noticed over in the Unity GUI the delay was still showing the older values and not updating properly. Restarting Unity fixed it.... The timer methods are exactly what I wanted. 0.1f is the perfect delay I was looking for!

    THANKS!
     
    Last edited: Jan 12, 2014
  9. marak-v1

    marak-v1

    Joined:
    Jul 7, 2013
    Posts:
    20
    I use on key up for the keyboard overrides (although this is only for the testing, so not sure how it will work in a production, mines touch screen primarily)
     
  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    That's only because of the default Unity settings for the Horizontal and Vertical axes, which have smoothing built-in, where it takes a second for the input to go back to 0. So I bumped the gravity and sensitivity to 99 and re-uploaded.

    --Eric
     
  11. NikVel

    NikVel

    Joined:
    Mar 20, 2016
    Posts:
    1
    This piece of code work just fine to slow down all your input:
    ...
    private float presedShiftInTime = 0; // Counter time for pressed button
    ...
    public float slowButonsPressed = 3; // magick number to "slow motion"

    void Player_Run()
    {

    if(Input.GetKey(KeyCode.LeftShift))
    {

    presedShiftInTime += Time.deltaTime*10;
    if(presedShiftInTime > slowButonsPressed)
    {

    player_Animator.SetBool("Run", true);
    }
    else
    {

    player_Animator.SetBool("Run", false);
    }
    }
    else if(Input.GetKeyUp(KeyCode.LeftShift))
    {

    presedShiftInTime = 0;
    player_Animator.SetBool("Run", false);
    }
    }