- Home /
Issue With Input.GetKey and IENumerator in Grabbing Script
So what Im trying to achieve here, is when the player holds down E it continously grabs the item and grabs certain increments per swipe. Now the way I set this up so far, is just to log a string of "Grabbing Item" In this case lets focus on 1 item, a large stack of money. My hope, was when the player is within the colliders of lets say (Money Stack), and if I am holding down E, then every X seconds, the Log should say, "Grabbing Money".
Now it does do this for sure, but its weird.. Lets say we set the EINumerator to yield for about 3 seconds.How its currently playing out, is it waits the 3 seconds but then BOMB! does the log about 20-30 times while im holding down E. If I am to just tap E, it literally does it like 10 times really fast.
Why the heck, is my code playing out this way? My theory is the logic I have for the collider.. I think that every split second my player is within the collider, it runs the IENumerator function multiple times within a second. This is the only thing I can think of. But at the same time, I'm not to sure of the proper approach/architecture I should be taking? Any advice is appreciated, thanks.
Code:
public class GrabMoneyStack : MonoBehaviour
{
// Variables:
[SerializeField] public int moneyAmt;
[SerializeField] public float grabSpeed;
public void OnTriggerStay(Collider other)
{
// check if its the player:
if(other.tag == "Player")
{
// Check to see if user HOLDS DOWN the "E" key:
if(Input.GetKey(KeyCode.E))
{
StartCoroutine(GrabMoney());
}
}
}
IEnumerator GrabMoney()
{
// yield return new WaitForSeconds(Time.deltaTime * grabSpeed);
yield return new WaitForSeconds(grabSpeed);
Debug.Log("Grabbed Money!");
}
}
Answer by RaptorRush · Aug 13, 2020 at 06:01 PM
“I think that every split second my player is within the collider, it runs the IENumerator function multiple times within a second.” Yes, that’s seems to be the problem.
To fix it, just make sure that the coroutine has ended before calling another one.
A simple bool is enough:
public class GrabMoneyStack : MonoBehaviour {
// Variables:
[SerializeField] public int moneyAmt;
[SerializeField] public float grabSpeed;
private bool grabbingMoney;
public void OnTriggerStay(Collider other) {
// check if its the player:
if (other.tag == "Player") {
if (Input.GetKey(KeyCode.E) && !grabbingMoney) { // start only is grabbingMoney == false
StartCoroutine(GrabMoney());
}
}
}
IEnumerator GrabMoney() {
grabbingMoney = true;
yield return new WaitForSeconds(grabSpeed);
Debug.Log("Grabbed Money!");
grabbingMoney = false;
}
}
Awesome! Thank you very much! I thought of doing just this, but I had my placement wrong with the setting of said bolean transition. Thanks!
Your answer
![](https://koobas.hobune.stream/wayback/20220613005605im_/https://answers.unity.com/themes/thub/images/avi.jpg)