Forum begins after the advertisement:
[Part 2] Inconsistent Dash Distance
Home › Forums › Video Game Tutorial Series › Creating a Metroidvania in Unity › [Part 2] Inconsistent Dash Distance
- This topic has 6 replies, 2 voices, and was last updated 7 months ago by Joshua.
-
AuthorPosts
-
May 15, 2024 at 11:33 pm #14678::
I’m using the following code to dash, and calculate its distance. Results can range from 4 units moved to 2, and more minor variations in between.
<code> private IEnumerator Dash() { Vector2 start = rbody.position; canDash = false; state = State.DASHING; animator.SetTrigger("dash"); rbody.gravityScale = 0; rbody.velocity = new Vector2(transform.localScale.x * dashSpeed, 0); if (IsGrounded()) Instantiate(dashDustEffect, transform); yield return new WaitForSeconds(dashTime); rbody.gravityScale = gravity; rbody.velocity = Vector2.zero; state = State.IDLE; yield return new WaitForSeconds(dashCooldown); canDash = true; CalculateDistance(start); } private void CalculateDistance(Vector2 originalPosition) { Vector2 distance = rbody.position - originalPosition; Debug.Log("Distance: " + distance.x); }</code>
Dash() is called by CheckDash():
<code> private void CheckDash() { if (isDashButtonPressed) { if (canDash && state != State.DASHING && airDashCount < maxAirDashes) { if (!IsGrounded()) airDashCount++; StartCoroutine(Dash()); } else if (!canDash) Debug.LogWarning("canDash is false."); else if (state == State.DASHING) Debug.LogWarning("State is DASHING."); } }</code>
And CheckDash() is running in Update():
<code> void Update() { ProcessInput(); if (state != State.DASHING) { Move(); CheckJump(); CheckDash(); SetTransformScale(); } }</code>
Putting the Dash() code in FixedUpdate() fixes the distance issue, but when input isn’t checked for in Update() input registration becomes very inconsistent. I’ve tried decoupling the logic, putting parts into Update() and parts into FixedUpdate(), but I can’t quite get things to work. Advice would be welcome!
May 16, 2024 at 12:14 pm #14680::I’ve tested your code out and nothing is wrong about it. Similarly, the code we use have just about the same effect. Both experience minor distance difference from dashing. Because of this, i suspect that the reason behind the inconsistency is the update rates in Unity not being fast/consistent enough to keep track of the
WaitForSeconds
accurately.Testing out the values of the distance, i can say that with a
dashTime
of [0.2], the player can move the correct distance ofdashSpeed * 0.2
. or have a distance of [0.22]. This can be evident if you use a smallerdashSpeed
value of [1] or [10].Moving the code to
FixedUpdate()
does not appear to solve this issue either as thedashTime
effectively increased to [0.22], with some inconsistencies to increase further to [0.24].Of course, in lower dashSpeed values, such an inconsistency is fine, but with higher values, the [0.02] difference is quite high. Thus, I would recommend using a method that does not involve
WaitForSeconds
but something more solid/accurate. Like using theCalculateDistance()
method you have.For instance, you could split up the
Dash()
code into two parts, one which activates the dash animation and speed boost, & a code to check if you’ve reached the desired destination of(originalPosition.x + _distance, rb.position.y)
, which then stops the dashing.May 16, 2024 at 3:49 pm #14681::Thank you for the reply! I didn’t realize just how much the margin of error scaled with the amount of ‘dashSpeed’ I multiplied with. I was using rather high numbers (70-120) to get that snappy ‘instant’ feel. With my current settings things still feel pretty good, with less variant in distance:
View post on imgur.com
After dashing a bunch of times, the largest difference is about ~0.6 (4.2 – 3.5999). I honestly have no idea whether this is acceptable; do games like Hollow Knight have 100% consistency? One might assume with gameplay sections like Path of Pain.
May 16, 2024 at 4:04 pm #14682::To add on, this is caused by Unity’s Project Settings for time, being at a fixed timestep of [0.02] which acts as the update rate for your physics engine and time. [Essentially 50fps].
So, good to keep in mind the limitation for unity’s update rate, but i recommend taking a shot at the suggestion of tracking the position difference instead of the time difference as when you have higher dashSpeed’s, it might do better to constrain the distance than the time.
You can also see this fixed time step affect other things such as character and camera jittering and how interpolate helps with it in our article here:
Fix jittery camera movement in Unity with Rigidbody Interpolate
To see exactly how timestep works for Unity, look into this.
May 16, 2024 at 4:10 pm #14683::Thanks for the extra information. Which makes me think: is there a reason why the guide doesn’t just interpolate from position A to B, depending on desired distance and speed? That should always be consistent. Although you’d have to do some extra raycasting work to avoid going through walls.
May 16, 2024 at 4:20 pm #14684::If you mean our Metroidvania series, the series was made a year prior and we weren’t aware of this issue until you pointed it out. [Rather minute detail so thanks for spotting this.] The current method appears to work well enough given the mechanic and so we didn’t think to interpolate it.
I’ll test out your idea and see what can be done to make it more reliable. I can potentially integrate a fix into the series sometime soon as I have only recently finished updating it at the moment.
May 16, 2024 at 5:12 pm #14685 -
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: