I'm an illustrator and pixel artist and I do not know programming at all. I've been studying it specifically to learn how to use Unity and I have no idea of what I'm doing most of the time. All I did so far was by watching YouTube videos and tweaking the code.
So anyways, I managed to make my character jump, double-jump, walk and all the animations seem to be working properly, but the dashing mechanics seems to ignore the speed multiplier. It even plays the dash animation and the trail renderer I told it to play, but the speed remains like the same as if it was just walking. Since I pretty much just copied things I saw other people do and don't quite know what I'm doing, I think my code might be a Frankenstein aberration. But if I'm not wrong it looks like it gets to the point where it triggers the Coroutine, since it plays the dash animation and and the trail renderer. Unity didn't point any errors. So here's the Coroutine I'm using:
private IEnumerator Dash()
{
canDash = false;
isDashing = true;
float originalGravity = rb2d.gravityScale;
rb2d.gravityScale = 0f;
rb2d.velocity = new Vector2(rb2d.velocity.x * dashingPower, 0f);
tr.emitting = true;
yield return new WaitForSeconds (dashingTime);
tr.emitting = false;
rb2d.gravityScale = originalGravity;
isDashing = false;
yield return new WaitForSeconds(dashingCooldown);
canDash = true;
}
Here's the full code for analysis
Thank you all very much in advance!
CodePudding user response:
So my knowledge on Unity is limited to a few classes I have taken and its funky to say the least. at the beginning of your code, in the full code link, you set the value for rb2d.velocity which sets your normal move speed. When you set your code for dashing above, your assigning a new value to rb2d.velocity, which is fine, the problem I would assume, comes in when you realize that setting a new value for rb2d.velocity in the dash portion overwrites your reference to speed in the original declaration.
I could be wrong but I would try changing
rb2d.velocity = new Vector2(rb2d.velocity.x * dashingPower, 0f);
to this
rb2d.velocity = new Vector2((moveInput * (speed * dashingPower), rb2d.velocity.y);
This would be my guess.
Edit: If this doesn't work I still believe your problem lies with your velocity declaration.
CodePudding user response:
The reason for this problem is the constant changes of velocity in other parts of the code, which eliminates the effect of the dash. Note that at the same time as running the dash, you set the velocity
back to the Move input
in the fixed Update code where each frame runs, so this code can not see even a single frame running the dash.
//Moves player on x axis
private void FixedUpdate()
{
moveInput = Input.GetAxisRaw("Horizontal");
// Here we have a constant change that inhibits the dash effect..
rb2d.velocity = new Vector2(moveInput * speed, rb2d.velocity.y);
}
How to Fix Problem?
Although the best code architecture should always be such that different parts do not interfere with each other and operate independently, creating a Boolean
that freeze normal input motion is not always the right way. In the code below, I tried to save the velocity value when pressing the dash key, as well as the mathematical direction of movement with the Mathf.Sign
function. It is now sufficient to apply force to the stored velocity for the entire duration of the dash, regardless of whether it is unavoidable:
private IEnumerator Dash()
{
canDash = false;
isDashing = true;
float originalGravity = rb2d.gravityScale;
rb2d.gravityScale = 0f;
// Dash Setup..
var baseVelocity = rb2d.velocity; // save base Velocity
var direction = Mathf.Sign(baseVelocity.x);
var time = dashingTime;
tr.emitting = true;
while (time > 0)
{
rb2d.velocity = baseVelocity new Vector2(direction * dashingPower, 0); // reference base Velocity for dash
time -= Time.deltaTime;
yield return new WaitForEndOfFrame();
}
// Finishing..
tr.emitting = false;
rb2d.velocity = Vector2.zero;
rb2d.gravityScale = originalGravity;
isDashing = false;
yield return new WaitForSeconds(dashingCooldown);
canDash = true;
}
Also, to avoid misalignment of frames in the Update
and Fixed Update
, it is better to move them all to one event.
private void Update()
{
if (isDashing) return;
if (Input.GetKeyDown(KeyCode.LeftShift) && canDash) StartCoroutine(Dash());
/// Moving input motion to Update
moveInput = Input.GetAxisRaw("Horizontal");
rb2d.velocity = new Vector2(moveInput * speed, rb2d.velocity.y);
///.....
}