#``` IEnumerator DelayedInput bool
1 messages ยท Page 1 of 1 (latest)
Wait you're starting the coroutine every frame???
wait also
you're onl;y modifying a local variable
bool _theinput is a parameter to your coroutine. Parameters are local variables
they cannot be read from outside the function
basically there's a lot wrong with this...
I see I'm not that experienced with coroutine ๐
well the local variable thing is not even a coroutine issue
but yeah starting a coroutine every frame is generally not the thing you want to be doing
can you explain in plain english what you are trying to achieve with this code?
It's only when Im inputing things but yeah I see
The purpose of the code is to handle movement with slight delay
Can you share the rest of the code? Not seeing the internals of those functions really limits my understanding of the current code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
Rigidbody2D _rb => GetComponent<Rigidbody2D>();
BoxCollider2D _collider;
public float _dirX = 0;
public float _dirY = 0;
[Tooltip("Walking speed in pixel per second")]
public float _speed;
public bool _inputLeft =false;
public bool _inputRight = false;
public float _inputDelay;
// Start is called before the first frame update
void Start()
{
_collider= this.transform.Find("Collider").gameObject.GetComponent<BoxCollider2D>();
}
// Update is called once per frame
void Update()
{
CheckInput();
CalculateForces();
}
private void CheckInput()
{
_dirX = Input.GetAxisRaw("Horizontal");
if (_dirX < -0.1f) StartCoroutine(DelayedInput(_inputLeft));
else if (_dirX > 0.1f) StartCoroutine(DelayedInput(_inputRight));
else
{
}
_dirY = Input.GetAxisRaw("Vertical");
}```
{
if (_inputLeft == true && IsGrounded())
{
_rb.velocity = new Vector2(-_speed, _rb.velocity.y); //* Time.deltaTime
}
else if (_inputRight == true && IsGrounded())
{
_rb.velocity = new Vector2(_speed, _rb.velocity.y); //* Time.deltaTime
}
else
{
_rb.velocity = new Vector2(0, _rb.velocity.y);
}
_inputLeft = _inputRight = false;
}
public bool IsGrounded()
{
RaycastHit2D hit;
hit = Physics2D.BoxCast(_collider.bounds.center, _collider.bounds.size, 0f, Vector2.down, .1f, LayerMask.GetMask("Floor"));
if(hit) Debug.DrawRay(hit.point, hit.normal, Color.green);
return hit;
}
IEnumerator DelayedInput(bool _theinput)
{
int delay = 0;
while (delay < _inputDelay)
{
yield return new WaitForEndOfFrame();
delay++;
yield return null;
}
Debug.Log("Loop");
_theinput = true;
}
}```
pls fix formatting
ok so first off
one major problem here is how you're trying to pass the _inputRight and _inputLeft variables as parameters here
and then modifying the parameters
when you do that you are creating a copy of the variable
and then just modifying the copy
ah shit okay
so your modification will not be visible anywhere else
you should just directly use the member variables
get rid of the parameters
another problem is that you will be starting these coroutines every frame as long as the joystick or keys are held down
which maybe is ok
so try just making that first change for now and see what happens, then we can clean it up further
Yup it"s working as intended now
ty ๐
{
int delay = 0;
while (delay < _inputDelay)
{
yield return new WaitForEndOfFrame();
delay++;
yield return null;
}
Debug.Log("Loop");
if (_direction == "right") _inputRight = true;
if (_direction == "left") _inputLeft= true;
}```
I will kjust note that the way you have written it, the timing will be very inconsistent
What do you mean by that ?
are you purposely trying to wait a number of frames instead of an amount of time?
Yes
and also if you wanted to just wait a number of frames, the way you're doing it is not really right
a single yield return null; waits one frame
I'm interested if you have a resource explaining the why of that ๐ง
so if you want to wait n frames you just do:
int n = 5;
while (n > 0) {
yield return null;
n--;
}```
oh so here the code make th thing wait 2 frmes .
not sure what you're going for with the yield return new WaitForEndOfFrame();
but the point of that thing is to wait till a specific part of the frame right before rendering for certain rendering effects.
Okay
{
int delay = 0;
while (delay < _inputDelay)
{
yield return null;
delay++;
}
Debug.Log("Loop");
if (_direction == "right") _inputRight = true;
else if (_direction == "left") _inputLeft= true;
}```
so soomething like that
yeah that works
just note that a certain number of frames will take a different amount of time on different hardware
Hmmm the Coroutine is run once per frame with the code above ?
Well that's a separate issue too
Since if (_dirX < -0.1f) StartCoroutine(DelayedInput(_inputLeft)); is being run in Update, it will start a whole new corooutine every frame as long as that is true
it might be fine
might not be
honestly I think there's a simpler way to do this whole thing
if you want to just buffer the input for a certain number of frames, you could do that in Update
tbh Im just testing things out for now so dont worry too much about it ๐ I would like to implement multiplayer later on and I wanted to test how input delay feels like
Something like this:
Queuer<Vector2> inputBuffer = new Queue<Vector2>();
int bufferSize = 2;
void Update() {
// add new input to the buffer
inputBuffer.Enqueue(new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")));
// read the oldest one if the buffer is filled enough
if (inputBuffer.Count > bufferSize) {
Vector2 input = inputBuffer.Dequeue();
ProcessMovement(input);
}
}```
it's just like a queue in a grocery store. Enqueue adds a new thing to the end of the line, Dequeue grabs the first thing in line. So the thing that got there first, comes out first.