Smooth 2D topdown movement using rigidbody.velocity. Problems with Vector2.Normalize, Mathf.Lerp and diagonal movement.
Hello!
I've been working on a 2D topdown shooter with randomly generating maps, pickups, waves of enemies etc. Recently I started fine-tuning the player movement, but ran into some problems, since I pretty much suck at maths and physics and end up getting confused with vectors. By the way, I'm using C#. Any help would be appreciated:
Originally I was using this piece of code:
void FixedUpdate()
{
GetComponent<Rigidbody2D>().velocity = new Vector2(Mathf.Lerp(0, Input.GetAxis("Horizontal") * speed, 0.8f), Mathf.Lerp(0, Input.GetAxis("Vertical") * speed, 0.8f));
}
It felt very responsive and the player turned and stopped smoothly. However there was one problem, which I came to find was asked here several times before. Diagonal movement (i.e. pressing W and D together) is noticeably faster than only horizontal or vertical movement.
Apparently double input causes the vector be longer and multiplied by speed it becomes faster. After reading through a fair amount of questions and forum posts, I came to the conclusion that I should normalize the vector. Here's what I tried:
void FixedUpdate()
{
Vector2 direction = new Vector2 (0,0);
direction.x = Input.GetAxis ("Horizontal");
direction.y = Input.GetAxis ("Vertical");
direction.Normalize ();
GetComponent<Rigidbody2D> ().velocity = direction * speed;
}
This does indeed seem to reduce the diagonal movement speed to about the same as vertical/horizontal.
However, now the movement becomes way less smooth than my previous attempt. Starting to move, stopping, and changing to the opposite direction mid-movement all happen in a very unnatural, snappy manner. A quick press of the button results in a big "leap" for the character instead of a small nudge. I assume this happens because the second piece of code has no Math.Lerp?
My attempts to combine the two have been unsuccessful. The end result usually behaves similar to either of the two. Also, simply normalizing my first attempt resulted in the speed variable not affecting movement speed at all. Instead it got also normalized into 1, right?:
void FixedUpdate()
{
GetComponent<Rigidbody2D>().velocity = new Vector2 (Mathf.Lerp(0, Input.GetAxis ("Horizontal") * speed, 0.8f), Mathf.Lerp(0, Input.GetAxis ("Vertical") * speed, 0.8f)).normalized;
}
So in a nutshell, my questions are:
How do I move a 2D character with a rigidbody using both Vector2.Normalize() and Mathf.Lerp, eliminating double speed for diagonal movement and making acceleration slightly smoothed?
or
Am I even in the right track? Is there an easier / more optimal way to do all this than what I've been trying?
Thanks in advance, and apologies for a (partly) already answered question.
Hello, sorry for bothering, i have the same problem as you do and i didn't find the solution. I've read your reddit post too but without any help. Did you find the solution on this problem? Or did you used another method?
@AngelDeads Okay, so, i found the solution:
GetComponent<Rigidbody2D>().velocity = Vector3.Clamp$$anonymous$$agnitude(movementDirection,1) * $$anonymous$$ovementSpeed;
You have to set the clamp magnitude to 1 and than multiply the whole resulted vector 3 with the speed. I made the mistake where I was multiplying this two inside the Clamp$$anonymous$$agnitude. I really hope you understood the solution if you still needed it.
You posted a comment as an answer and then an answer as a comment to that answer...
I'll convert
Your answer
![](https://koobas.hobune.stream/wayback/20220612084807im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Unity Space Shooter Tutorial Player Will Not Move 1 Answer
Controller script active on both characters. 1 Answer
How do I create a 2D movement script that will cause prefabs to drift around the screen? 0 Answers
[Android] Character movement script help 1 Answer
Failed to create agent because it is not close enough to the NavMesh 4 Answers