Hey,
What i want to do is when you hold down a key for x amount of seconds it wil do something.
And if you released the key before you reached the x amount of seconds it will not do anything.
But how can i Achieve this?
All help is Appreciated!!!
this is what i have but don’t think this is the best way can this be done easier?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour {
public KeyCode Key;
public float HoldTime;
bool StartTimer;
void Update()
{
if (Input.GetKeyDown(Key))
{
StartTimer = true;
StartCoroutine(HoldTimer());
}
if (Input.GetKeyUp(Key))
{
StartTimer = false;
}
}
IEnumerator HoldTimer()
{
Debug.Log("Starting Timer!");
yield return new WaitForSeconds(HoldTime);
if(!StartTimer)
{
Debug.Log("broke");
}
else
Debug.Log("Timer ENDED!");
}
}
// Warning pseudo code
float startTime = 0f;
float holdTime = 5.0f; // 5 seconds
if GetKeyDown(key)
startTime = Time.time;
if GetKey(key)
// check if the start time plus [holdTime] is more or equal to the current time.
// If so, we held the button for [holdTime] seconds.
if startTime + holdTime >= Time.time;
DoSomething();
Time.time returns the time since the game started in seconds, by catching the time the moment the button is pressed we get the start of the hold action. By adding the prefered time you want people to hold the button to that and comparing that to the current Time.time value we can see whether 5 seconds has passed.
But even if the number is 1 or 2 or whatever number it will show the debug.
Did i do something wrong?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour {
public KeyCode Key;
public float startTime = 0f;
public float holdTime = 5.0f; // 5 seconds
void Update()
{
if (Input.GetKey(Key))
{
startTime = Time.time;
if (startTime + holdTime >= Time.time)
Debug.Log("It Works Great!");
}
}
}
I believe input.GetKey gets the key status each frame where as input.GetKeyDown is only true when the key is first pressed so you would need to put startTime = Time.time in an if statement for GetKeyDown.
So I figure that this is mostly dead, but here’s the code that I used after reading your replies:
using UnityEngine;
public class KeyboardControls : MonoBehaviour {
// Timer controls
private float startTime = 0f;
private float timer = 0f;
public float holdTime = 2.0f; // how long you need to hold to trigger the effect
// Use if you only want to call the method once after holding for the required time
private bool held = false;
public string key = "g"; // Whichever key you're using to control the effects. Just hardcode it in if you want
void Update ()
{
// Starts the timer from when the key is pressed
if (Input.GetKeyDown(key))
{
startTime = Time.time;
timer = startTime;
}
// Adds time onto the timer so long as the key is pressed
if (Input.GetKey(key) && held == false)
{
timer += Time.deltaTime;
// Once the timer float has added on the required holdTime, changes the bool (for a single trigger), and calls the function
if (timer > (startTime + holdTime))
{
held = true;
ButtonHeld();
}
}
// For single effects. Remove if not needed
if (Input.GetKeyUp(key))
{
held = false;
}
}
// Method called after held for required time
void ButtonHeld()
{
Debug.Log("held for " + holdTime + " seconds");
}
}
Hello, this is an interesting topic. I basically want to know how would I edit my timer and player script to do something similar. My game is taking an input from two push buttons connected to an arduino .
This is the PlayerController script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
public class PlayerController : MonoBehaviour
{
SerialPort sp = new SerialPort("\\\\.\\COM4", 9600);
//player = GameObject.FindWithTag("Player").GetComponent<Renderer>().material;
public float Speed;
public Vector2 height;
public float xMin, xMax, yMin, yMax;
void Awake()
{
//player = GameObject.FindWithTag("Player");
}
void Start()
{
if (!sp.IsOpen)
{ // If the erial port is not open
sp.Open(); // Open
}
sp.ReadTimeout = 1; // Timeout for reading
}
public void Update()
{
if (sp.IsOpen)
{ // Check to see if the serial port is open
try
{
string value = sp.ReadLine();//To("Button"); //Read the information
int button = int.Parse(value);
//float amount = float.Parse(value);
//transform.Translate(Speed * Time.deltaTime, 0f, 0f); //walk
if (button == 0) //*Input.GetKeyDown(KeyCode.Space*/) //jump
{
GetComponent<Rigidbody2D>().AddForce(height, ForceMode2D.Impulse);
}
GetComponent<Rigidbody2D>().position = new Vector3
(
Mathf.Clamp(GetComponent<Rigidbody2D>().position.x, xMin, xMax),
Mathf.Clamp(GetComponent<Rigidbody2D>().position.y, yMin, yMax)
);
}
catch (System.Exception)
{
}
}
void ApplicationQuit()
{
if (sp != null)
{
{
sp.Close();
}
}
}
}
}
And this is the timer script:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class Timer : MonoBehaviour
{
public int timeLeft;
public Text countdownText;
// Use this for initialization
void Start()
{
StartCoroutine("LoseTime");
}
// Update is called once per frame
void Update()
{
countdownText.text = ("Time Left = " + timeLeft);
if (timeLeft <= 0)
{
//StopCoroutine("LoseTime");
//countdownText.text = "Times Up!";
Invoke("ChangeLevel", 0.1f);
}
}
IEnumerator LoseTime()
{
while (true)
{
yield return new WaitForSeconds(1);
timeLeft--;
}
}
void ChangeLevel()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}
}