Hi there. I’m trying to make a game similar to Enter the Gungeon, but I’m having problems with a dodge roll-like mechanic. My problem here is that my character teleports instead of moving when she performs a combat roll (Shown in the video).
My code is as follows:
public void CombatRoll() //Right Click to Combat Roll
{
if (Input.GetMouseButtonDown(1) && rolling == false)
{
//Debug.Log("Rightclicked");
if (Input.GetKey(KeyCode.D))
{
Debug.Log("D");
animator.SetBool("CRolling", true);
rolling = true;
immune = true;
Vector3 rollDistance = new Vector3(+30, +0, 0f) * speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, rollDistance, speed * Time.deltaTime);
Debug.Log("CombatRollRight");
Invoke("RollCooldown", 1);
Invoke("ImmuneRoll", 0.4f);
}
}
}
MoveTowards should take the current position, and the destination, not just an offset “rollDistance”.
Also, MoveTowards will only move a small increment towards the destination each frame, with a max distance of “speed * Time.deltaTime” per function call.
So when you detect a roll needs to happen, you need to store the final position, and then every frame call MoveTowards from the current position to the destination until it reaches it.
You could have a class-level variable to hold the destination, but I think a more straightforward way is to create a Coroutine that handles the the roll in a loop until it’s done. (or get a tweening package like DOTween)
Here’s an example of what that might look like:
public float rollDistance = 30;
public float rollSpeed = 1;
private bool rolling;
private bool immune;
private Animator animator;
private void Update() {
CombatRoll();
}
private void CombatRoll()
{
// if currently rolling, do nothing
if (rolling) {
return;
}
// just right clicked and holding D
if (Input.GetMouseButtonDown(1) && Input.GetKey(KeyCode.D) )
{
Debug.Log("CombatRollRight");
// start the coroutine, pass the movement offset (can be reused for other directions)
StartCoroutine(CombatRollCoroutine(Vector3.right * rollDistance));
}
}
private IEnumerator CombatRollCoroutine(Vector3 rollOffset) {
animator.SetBool("CRolling", true);
rolling = true;
immune = true;
Vector3 destination = transform.position + rollOffset;
while (transform.position != destination) {
transform.position = Vector3.MoveTowards(transform.position, destination, rollSpeed * Time.deltaTime);
yield return null; // wait until next frame to continue the loop
}
// i assume these set the bools to false
Invoke("RollCooldown", 1);
Invoke("ImmuneRoll", 0.4f);
}
I’m not sure if these issues cause the teleportation, but this shouldn’t teleport. If the character still teleports, then it’s possibly your animations causing it. Hope that helps, let me know if you have questions.