Access to float seconds ago

So What I want to do is to make my character move 1.0f after I press the arrow key / stop 1.0f after I release the arrow key. To make a delay in the action. So I did some expriments with Invoke here


private float WalkDelay;
private float WalkDelay2;

void FixedUpdate()
{
    WalkDelay = Input.GetAxisRaw("Horizontal");
    Invoke("WDelay", 1.0f);

    rb.velocity = new Vector2(WalkDelay2 * speed, rb.velocity.y);
}

void WDelay()
{
    WalkDelay = WalkDelay2;
}

But obviously it won’t work cause no matter how much frame I put before the Invoke, the WalkDelay2 will always get the current WalkDelay not WalkDelay Seconds ago. I Know why it doesn’t work but I have no idea how i can make it work. Can someone please help me?

+Sorry my code looks all messy in the posting I don’t know why it looks like that…

Well yes this solution as you currently have it can not work. i’d suggest you try something like this:
Something like this following should work as it uses coroutines where you can pass an argument to the function:

private float lastInput = 0f;
private float delayedMovementInput = 0f;

public void Update()
{
	//make sure you always check for input in Update and not in FixedUpdate
	float newInput = Input.getAxisRaw("...");
	if(newInput != lastInput) //whenever the input changes start a coroutine to apply that input delayed
	{
		StartCoroutine(setNewMovementInputDelayed(newInput));
		lastInput = newInput;
	}

	rb.velocity = new Vector2(delayedMovementInput * speed, rb.velocity.y); // move by delayedInput
}

private IEnumerator setNewMovementInputDelayed(float newInput, float delay= 1f)
{
	yield return new WaitForSeconds(delay);
	delayedMovementInput = newInput;
}

Let me know if that helped.

You could use coroutines like Captain showed in his answer, though this creates garbage. An alternative would be to simply use a Queue. A simple implementation may just delay for a certain amount of frames by simply pre-filling the queue with that amount of values and each frame simply queue the current input and dequeue the oldest. That way the length of the queue stays the same and you get X amount of frames delay. Of course, this is not frame rate independent. Though the length of the queue could be set dynamically once so the only effect keft would be frame rate fluctuations but huge framerate differences between several devices would not be an issue.

Of course you can do also use a queue where you queue up the current input value with a timestamp and when dequeuing the input for this frame, you would simply peek into the queue to see if the oldest time has expired and then dequeue until you get a non-expired time. This would make it fully framerate independent.

Currently I don’t have time to write up an example, but you should get the idea ^^.