Search Unity

Making a character go from walking to running by pressing the input twice

Discussion in 'Scripting' started by JoeCullum, Jan 3, 2017.

  1. JoeCullum

    JoeCullum

    Joined:
    Dec 27, 2016
    Posts:
    18
    What way is there that I can do this?
     
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    You need to check the state of the mouse each frame (is pressed, is held or is release) and you're looking for a pattern of press -> release -> hold or hold -> release -> hold that takes place in x seconds. Because releasing a key can only be done after pressing it, you're really looking for something like this: release -> hold. I would do this, by setting a counter every time the player releases the key (Input.GetKey/ButtonUp) to some seconds ( 0.1 seconds would be good I think), each frame I would substract the deltaTime and while it's not 0, I would check for a hold (Input.GetKey/Button)
     
  3. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    You could keep track of when the input has pressed for the last time; just store Time.time or Time.realtimeSinceStartup into a variable. Then each time the input is pressed, compute the duration since the last time it has been pressed. If the duration is less than a given threshold, consider it as a double press. Then you would need to adjust the character speed and animation accordingly.
     
  4. JoeCullum

    JoeCullum

    Joined:
    Dec 27, 2016
    Posts:
    18

    I'm sorry, this is a brilliant response but it feels like I asked a question beyond my capabilities at this point and don't fully understand what you're saying. Is it okay if you could go into more detail with this? I'm with you up to the point where you subtract the deltaTime each frame. Thank you
     
  5. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    You set a float value to let's say 0.1, this is your cooldown period, if you release then press the same button in this timefram you will get a double press. So you have a value set to 0.1 each time you release the forward key, now we want to make this counter functional, so we want to substract the time that passed since the last frame. This can be done by yourCounterNameHere - Time.deltaTime;
    now your variable is 0.1 at the start and it will reach 0 in about 0.1 seconds (Time.deltaTime won't reach exactly 0, it will most likely be -0.03 or something, so after the substraction you need to check if it's less than 0 and set it to 0 if yes)
    Now we need the last if statement
    if (buttonIsHeldDown && counter > 0)
    run

    This whole thing looks like this in pseudocode:
    Code (CSharp):
    1. counter := your counter
    2. cooldown := max time between key presses to count  as a double press
    3. if walkButtonIsReleased then
    4.     counter = cooldown
    5. endif
    6.  
    7. if counter > 0 then
    8.     if walkButtonIsPressed then
    9.         You are running
    10.     endif
    11.     counter -= Time.deltaTime
    12.     if counter < 0 then
    13.         counter = 0
    14.     endif
    15. endif
     
    MarshianMan likes this.
  6. JoeCullum

    JoeCullum

    Joined:
    Dec 27, 2016
    Posts:
    18
    Okay so my code looks like this after reading that, and honestly this looks a lot like the code I did after the first reply you wrote. This all makes sense in my head. Am I missing something?


    Code (csharp):
    1.  
    2. if (Input.GetKey(KeyCode.D))
    3.         {
    4.             moveVelocity = moveSpeed;
    5.            
    6.         }
    7.         if (Input.GetKeyUp(KeyCode.D))
    8.         {
    9.             runThresholdCounter = runThreshold;
    10.  
    11.             if (runThresholdCounter > 0)
    12.             { if (Input.GetKey(KeyCode.D))
    13.                     moveVelocity = runSpeed;
    14.             }
    15.             runThresholdCounter -= Time.deltaTime;
    16.             if (runThresholdCounter < 0)
    17.             {
    18.                 runThresholdCounter = 0;
    19.             }
    20.         }
    21.        
     
  7. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Yes, first of all, you don't want to put everything inside Input.GetKeyUp, only the runTresholdCounter = ... line
    then you want to have everything else be in if runTresholdCounter > 0 because then you wont substract Time.deltaTime every time, only when needed
     
  8. JoeCullum

    JoeCullum

    Joined:
    Dec 27, 2016
    Posts:
    18
    Okay, so I think I've just put the runThresholdCounter = runThreshold in the GetKeyUp statement. and It looks like I've put everything inside the runThresholdCounter > 0 statement here. Is there anything else I'm missing? Or is there something else I overlooked?


    Code (csharp):
    1.  
    2. if (Input.GetKey(KeyCode.D))
    3.         {
    4.             moveVelocity = moveSpeed;          
    5.         }
    6.        
    7.         if (Input.GetKeyUp(KeyCode.D))
    8.         {
    9.             runThresholdCounter = runThreshold;
    10.         }
    11.        
    12.         if (runThresholdCounter > 0)
    13.         {
    14.             if (Input.GetKey(KeyCode.D))
    15.             {
    16.                 moveVelocity = runSpeed;
    17.             }
    18.                 runThresholdCounter -= Time.deltaTime;
    19.                 if (runThresholdCounter < 0)
    20.                 {
    21.                     runThresholdCounter = 0;
    22.                 }
    23.         }
    24.  
     
  9. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Yeah that's it, for the matter of fact if you look at the pseudocode I posted it should be the same
     
    MarshianMan likes this.
  10. Vancete

    Vancete

    Joined:
    May 3, 2010
    Posts:
    198
    Using the 'Input.GetKey(KeyCode.D)' more than once one into another doesn't make sense, since them will be all true or false in a single loop.
     
  11. MarshianMan

    MarshianMan

    Joined:
    Mar 27, 2015
    Posts:
    50
    I agree, I think if he removed the Input.GetKey from within the "if (runThresholdCounter > 0)" if-statement he should be fine.