I tried to implement a Megaman-x-like dash in my code a few times but failed miserably. Took a few step backs and tried to breakdown how a Megaman x dash really works.
I got this:
- when you press the dash button without directional influence, you’re sent to the direction you’re looking;
- the dash works like a “better jumping”, as in whenever you hold it, it applies a force to the desired direction. however after a period of time/releasing the dash button, it stops. literally like a normal “mario jump” but with horizontal movement.
- the dash cant be done on the air
- your speed increases whenever you dash (duh)
- you can “spam dash” [though i think if you do it your speed decreases a little?]
- you can quickly change the direction of your dash with directional input, even when you are dashing
though I’ve been struggling a little to get this one down to code.
I’d love to ask two questions, one is how to become better at this “second stage”, that is, turning your “breakdown” into actual code, and if you guys can help me out with some guidance. It would be really appreciated. Just for the sake of it, here is my player movement code:
Note: I don’t have a ground check bc I was having some problems with it. I’m temporarily using
rb.velocity.y
as ground control
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
#region VARIABLES
[Header("Components")]
public Rigidbody2D rb;
[Space(20)]
[Header("Movement Settings")]
float defaultSpeed;
float defaultMaxAcel;
public float maxAcel = 2;
public float acel = 1;
public float speed;
public float targetSpeed;
[Range (-1f, 1f)] public float deAccel = 0.5f;
private float mov;
[Space(20)]
[Header("Jump and Gravity settings")]
public float jumpBuffer;
public float jumpBufferTime = 0.2f;
public float jumpPower;
public float defaultGravity;
public float gravityInc = 2;
public float lowFallMult = 2;
public bool jumped;
[Space(20)]
[Header("Other settings")]
public float lerpingSpeed = 10;
float defaultLerpingSpeed;
public float antiAirLerpingSpeed;
public float TimeMult = 2;
#endregion
void Start()
{
if (rb == null)
{
this.enabled = false;
Debug.Log("RB not found. check if gameObject has component R2D.");
}
defaultGravity = rb.gravityScale;
defaultSpeed = speed;
defaultMaxAcel = maxAcel;
defaultLerpingSpeed = lerpingSpeed;
}
void Update()
{
if (rb.velocity.y == 0)
{
jumped = false;
speed = defaultSpeed;
maxAcel = defaultMaxAcel;
lerpingSpeed = defaultLerpingSpeed;
}
if (Mathf.Abs(rb.velocity.y) > 0 && jumped)
{
antiAccelOnAir();
}
rb.gravityScale = defaultGravity;
mov = Input.GetAxisRaw("Horizontal");
if (acel < maxAcel && mov != 0 && rb.velocity.y == 0)
{
acel += Time.deltaTime * TimeMult;
}
else if (acel <= maxAcel && (mov == 0 || rb.velocity.y != 0))
{
acel = 1;
}
else
{
acel = maxAcel;
}
if (Input.GetKeyDown(KeyCode.Space))
{
jumpBuffer = jumpBufferTime;
}
else
{
jumpBuffer -= Time.deltaTime;
jumpBuffer = Mathf.Max(jumpBuffer, -1);
}
if (jumpBuffer > 0 && rb.velocity.y == 0)
{
Jump();
jumped = true;
jumpBuffer = 0;
}
if (rb.velocity.y < 0)
{
rb.gravityScale = defaultGravity + gravityInc;
}
else if (rb.velocity.y > 0 && !Input.GetKey(KeyCode.Space))
{
rb.velocity += Vector2.up * Physics2D.gravity.y * lowFallMult * Time.deltaTime;
}
targetSpeed = speed * mov * acel;
}
void FixedUpdate()
{
float smoothVelocity = Mathf.Lerp(rb.velocity.x, targetSpeed, lerpingSpeed * Time.fixedDeltaTime);
rb.velocity = new Vector2(smoothVelocity, rb.velocity.y);
if (mov == 0 && rb.velocity.y == 0)
{
rb.velocity = new Vector2(smoothVelocity * deAccel, rb.velocity.y);
}
}
void Jump()
{
rb.velocity = new Vector2(rb.velocity.x, jumpPower);
}
void antiAccelOnAir()
{
speed = speed * maxAcel;
maxAcel = 1;
acel = 1;
lerpingSpeed = antiAirLerpingSpeed;
}
}