- Home /
2D dash in coroutine Inconsistent
Hello, I am trying to do a 2D dash effect. I am using a coroutine to do it. The problem is that the distance the player travels is inconsistent. Its close but not fully accurate. How can I fix it? The necessary sample of the code is below. Thank you.
public override IEnumerator Cast()
{
canCast = false;
controls.canMove = false;
float curTimeLeft=dashDuration;
controls.rb.velocity=new Vector2(0,0);
Vector2 dasher = transform.right ;
controls.rb.velocity = dasher*dashSpeed;
yield return new WaitForSeconds(dashDuration);
controls.rb.velocity=new Vector2(0,0);
controls.canMove = true;
yield return new WaitForSeconds(cooldown);
canCast = true;
}
Hello, I really can't figure out what causes this problem. Does anyone have any idea?
Answer by Bunny83 · Sep 30, 2020 at 09:08 AM
Physics usually run on the FixedUpdate cycle which is more or less independent from the framerate and the Update cycle. WaitForSeconds can only wait approximately for the given time. Since it can only continue after a full frame the time could always be slightly more than what you have specified. Instead of
yield return new WaitForSeconds(dashDuration);
you might be able to use
float timeOut = Time.fixedTime + dashDuration;
while(Time.fixedTime < timeOut)
yield return null;
instead.
Of course since you set your velocity only once at the beginning of your dash, it's possible that due to collisions or friction you loose momentum. Maybe you want to set the velocity every frame during the dash?
float timeOut = Time.fixedTime + dashDuration;
while(Time.fixedTime < timeOut)
{
controls.rb.velocity = dasher*dashSpeed;
yield return null;
}
Thank you very much, I think this worked. I have couple questions though if you don't $$anonymous$$d replying. First questions is, does this mean that I shouldn't count on "wait for seconds" for my cooldown tracking also? since it wont be accurate fully accurate with the cooldown I will have varying cooldowns? Also even in this code you sent
while(Time.fixedTime < timeOut)
{
controls.rb.velocity = dasher*dashSpeed;
yield return null;
}
since the while loop will not exit at the EXACT moment that Time.fixedTime== timeOut, in theory I should have some varying distances no? Is this how all games does it? How do they achieve such pixel perfection then? Like I see that games like Hollow Knight the dash distance seems to be always same amount, and that game is also built in unity.
Thank you for your time!
Hello again, sorry to bother you again but I just wanted to bump my question incase you are available to answer it @Bunny83 . Again thank you for your time!
Well, first of all anything based on time is not 100% accurate. However things based on the fixed time is at least consistent because we get the same amount of frames. Physics is not calculated every visual frame but every fixed update frame. So your rigidbody only moves at the fixed update rate. When we use the fixed time we should get a consistent fixed update call count.
However as I already mentioned if you have friction, collisions or other external forces the resulting distance of course will be different. However not due to the time but just many other factors.
It's up to you how you want to implement your game mechanics. You shouldn't focus too much on other games. You should define how you want it to behave and then implement it that way :) If you want to base your dash on a certain distance rather than a certain time you may want to use the distance travelled as a condition rather than the time. However how practical is that? Have you throught of edge cases? What if you dash into a wall? What if you dash over a cliff? How much control should the user have during the dash? There are countless of different ways how you could implement such a mechanic. One way could even be to deter$$anonymous$$e the landing spot at the moment you start the dash by using complex raycasing and probing so in the end you know exactly where you want to land and just need to somehow lerp to the result.
So there is no definite answer to your questions. It depends on your vision and your wanted behaviour. In an action game it's often more important to have fluent movement and responsive controls rather than 100% accurate behaviour. I never played Hollow Knight but from what I've seen it's not really "pixel perfect". I've seen people dash into walls in order to perform a wall jump. So in this case the dash didn't travel the whole distance. Haven't seen any dashing on slope as the game doesn't seem to have much of them.
I see, thank you very much this was very helpful for my understanding!