- Home /
is there any easier way to do this ?
this is the problem when character is idle, i want to start coroutine once, and when user presses any button, i want to stop the coroutine once. problem is code to check if user is in idle or moving is in update function.
this is my solution
private void Update()
{
CheckIdle();
}
private bool MoveCheck, TimerCheck;
private void CheckIdle()
{
MoveCheck = Input.GetAxis("Vertical") == 0 && Input.GetAxis("Horizontal") == 0;
if (MoveCheck) // character is in idle
{
if (!TimerCheck) // timer has not started yet
{
TimerCheck = true; // timer started
StartCoroutine(Idling());
}
}
if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
{
if (TimerCheck) // timer is on
{
TimerCheck = false; // stop timer
StopCoroutine(Idling());
}
}
}
this works well but code looks messy. is there any simpler way to do it? can event and delegate help me in this scenario ? if yes, how ?
@Hellium you are the only guy i turn to when no one else help. hope im not bothering you.
Answer by sharatachary · May 14 at 02:44 PM
Hello @acclogin71 ,
Please have a look at this IdleMonitor implementation, hope this helps.
/* author : Sharat Achary
* date : 20220514
*/
using System.Collections;
using UnityEngine;
public class IdleMonitor : MonoBehaviour
{
private bool isIdling;
private void Start()
{
StartIdling();
}
private void Update()
{
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.D))
{
// Cancle any invoke.
CancelInvoke("StartIdling");
if (isIdling)
{
StopIdling();
}
}
if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.S) || Input.GetKeyUp(KeyCode.D))
{
if (!isIdling)
{
// Add a delay of 1f second so that we make sure during that delay any w-a-s-d key are registered.
Invoke("StartIdling", 1f);
}
}
}
private void StartIdling()
{
isIdling = true;
Debug.Log("----- Start Idling Coroutine.");
StartCoroutine("Idling");
}
private void StopIdling()
{
isIdling = false;
Debug.Log("----- Stop Idling Coroutine.");
StopCoroutine("Idling");
}
private IEnumerator Idling()
{
while (true)
{
Debug.Log("Player is idling");
yield return new WaitForSeconds(1f);
}
}
}
Answer by xxmariofer · May 13 at 09:11 AM
is hard to tell without seeing the full code, if thats the full code and you are not reading the inputs somewhere else then you cant simplify your code with events or delegates
all i want to do is start a timer when w-a-s-d keys are not pressed, stop the timer when any of those keys are pressed. checking if any key is pressed or not can only happen inside update function, and when any key is not pressed, i want to start the timer from update function, only once.
Your code is fine, and there are no real benefits from refactoring, leaving as it is. I would simply remove the Invoke method, and instead add a delay using WaitForSeconds inside the coroutine itself. But you can't simplify much that code
Your answer
Follow this Question
Related Questions
"The event can only appear on the left hand side of `+=' or `-=' operator" 1 Answer
When to use 'delegate', 'event' or 'Action' ? 1 Answer
Login form: Do I have to set custom delegates to null in OnDestroy? 0 Answers
C# Action from Event 1 Answer
How do convert a lambda event subscription to be able to unsubscribe it? 2 Answers