# Slowing movement while turning

Hi,
I’m trying to slow down the x factor of the velocity after turning mid air. (jumping and then moving to the opposite side)
I spent most of the day trying and coding some stuff, but couldn’t manage to work it out… any help would be appreciated!

Here’s my simple code for movement.
*Note that I don’t want to add acceleration to the movement.

``````  moveInput = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
``````

@Dedi6

Well after half a day, you don’t have anything, except the basic movement you began with?

Anyway try to do pseudo code first - this is mine after a while of thinking (I usually struggle with logic, unless I rubberduck / do pseudo code - try it).

• When jumping store the jump state in bool.
• Store move directionNow each frame while jumping.
• Each frame check input. Get the moveInput.
• Calculate moveInput multiplied by speed to some temporary variable.
• Next, if moveInput is different than directionNow, flip the player.
• Also, halve the temporary move speed as player changed direction.
• Apply temporary speed to player’s velocity.

When player hits ground after jump, disable above direction check. Don’t modify the speed if player changes direction either.

Actually I’ve already wrote this solution but didn’t manage to get it right. I’ll give it another try, thanks @eses !

BTW, that is what I worked on for the last couple of minutes with my brother but it doesn’t seem to work also

``````  moveInput = Input.GetAxisRaw("Horizontal");

if ((rb.velocity.x > 0 && moveInput < 0) || (rb.velocity.x < 0 && moveInput > 0))
{
dragTime -= Time.deltaTime;
if (dragTime <= 0)
{
rb.velocity = new Vector2(0, 0);
Debug.Log("hi");
}
}
if ((rb.velocity.x >= 0 && moveInput >= 0) || (rb.velocity.x <= 0 && moveInput <= 0))
{
dragTime = 1f;
rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);

}
``````

Note that the debug does print the hi, but it doesnt stop the motion. (we’ve stopped the motion entirely instead of gradually increasing it to test if the code works.

Check out this solution using a simple Coroutine. Just tell me if there is something you don’t understand. Coroutines can get very interesting in certain cases, you should check about these if you have the time. I didn’t test the script, but it should work as is .

``````using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Testingblabla : MonoBehaviour
{
float speed;
float TimeItTakesToReachMaxSpeedAgain = 1f;
float speedModifier = 1f;
float moveInput;
Rigidbody2D rb;

public IEnumerator SmoothlyGetMySpeedAgain() // This is a coroutine, once you start it, it will call itself automatically until the while loop ends. (in this case, when the speed comes back to normal, it will stop itself)
{
while (speedModifier < 1f)
{
speedModifier += Time.deltaTime / TimeItTakesToReachMaxSpeedAgain;
if (speedModifier > 1)
{
speedModifier = 1; // We don't let the speed modifier get bigger than ONE, else your player might end up running faster.
}
yield return null; //A magic word for the coroutine, this one will just make it wait for next frame update before looping again.

}
}
private void Update()
{
moveInput = Input.GetAxisRaw("Horizontal");

if ((rb.velocity.x > 0 && moveInput < 0) || (rb.velocity.x < 0 && moveInput > 0))
{
if (speedModifier == 1f)
{
speedModifier = 0f;//We set the speed modifier to zero to decrease the movement. You can set it to 0.5f or something if you don't want to entirely stop the movement.
StartCoroutine("SmoothlyGetMySpeedAgain");//Since the speed modifier was equal to ONE, it means the coroutine wasn't running, we need to start it.
}
else
{
speedModifier = 0f;//Since the speed modifier wasn't equal to ONE, it means the coroutine was already running. We just need to adjust the speedModifier then.
}
}
if ((rb.velocity.x >= 0 && moveInput >= 0) || (rb.velocity.x <= 0 && moveInput <= 0))
{

rb.velocity = new Vector2(moveInput * speedModifier * speed, rb.velocity.y);//We just multiply the normal speed by the speed modifier to adapt the speed.

}
}

}
``````

@hlw Thank you very much!
I actually never heard of a Coroutine and it’s really nice learning new stuff.
There are two things I didn’t understand :

1. I wrote almost the exact code as yours, but instead of the while being inside a Coroutine it was inside a function. It didn’t work for me. What is the difference between a while and a while inside a Coroutine? I watched some youtube videos which said that when calling a Coroutine, the program will only run the Coroutine until it is finished. Is that the difference?
2. Is there a specific reason to make the Coroutine wait for a frame before resuming?
Or is it just the way Coroutine works and that’s the minimum wait time ?

Putting a while inside a normal method will make it loop multiple times inside the same frame, which means it will instantly jump to max speed instead of smoothly accelerate. You are not forced to use a coroutine to achieve that, you could get the same behavior using if statement inside the update loop.
I’m not sure if you are forced to wait or not with coroutines, as I mostly use them for their ability to wait for the time you ask them to.

1 Like