Unity 2D Top Down Shooter movement issue C#
c#, game-physics, topdown, unity-game-engine
Solution
You start with a velocity of 0, then you add up all the movements directions you have. Then you normalize the vector and scale it to your movement speed. Otherwise the player moves faster, if walking diagonal.
I haven't checked the code, but something like this will do:
void Update () {
Vector3 vel = new Vector3();
if(Input.GetKey(Up)){
Debug.Log("UP");
Vector3 velUp = new Vector3();
// just use 1 to set the direction.
velUp.y = 1;
vel += velUp;
}
else if(Input.GetKey(Down)){
Vector3 velDown = new Vector3();
velDown.y = -1;
vel += velDown;
}
// no else here. Combinations of up/down and left/right are fine.
if(Input.GetKey(Left)){
Vector3 velLeft = new Vector3();
velLeft.x = -1;
vel += velLeft;
}
else if(Input.GetKey(Right)){
Vector3 velRight = new Vector3();
velRight.x = 1;
vel += velRight;
}
// check if player wants to move at all. Don't check exactly for 0 to avoid rounding errors
// (magnitude will be 0, 1 or sqrt(2) here)
if (vel.magnitude > 0.001) {
Vector3.Normalize(vel);
vel *= walkSpeed;
rigidbody2D.velocity = vel;
}
//rotation
Vector3 mousePos = Input.mousePosition;
Vector3 objectPos = Camera.main.WorldToScreenPoint (transform.position);
mousePos.x = mousePos.x - objectPos.x;
mousePos.y = mousePos.y - objectPos.y;
float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
}
Regarding `Normalize` have a look at this image.
If you walk only upwards or right you would move with speed 1 (which we later multiply with your desired speed). But if you walk diagonal you walk with about 1.4 times the desired speed (green vector). `Normalize` keeps the direction of the vector intact, but gives you a length (also called "magnitude") of 1 (red vector).
In older shooters you may find a bug called "bunny hopping". I'm not sure if this is the source of the problem, but I would guess it is.
Regarding `vel.magnitude > 0.001`:
We actually want to know if `vel.magnitude > 0`. But `vel.magnitude` is the result of a calculation and thus may contain rounding errors. If you work with floating-point values always keep that in mind. The check itself is done because the `Normalize` method needs to divide by the magnitude and division by zero is evil. Not sure if `Normalize` checks for this itself.
Problem
I am trying to make a simple 2D Top-Down Shooter in Unity. I have the basic movement and following of the mouse, but there is an issue in the movement. Whenever you press say Up and Right at the same time, it moves diagonally as you would expect, but when you let go of the Up key, it keeps going diagonally where I want it to move Right. My code for handling the movement is: ``` private void Update () { if (Input.GetKey(Up)) { Debug.Log("UP"); Vector3 velUp = rigidbody2D.velocity; velUp.y = walkSpeed; rigidbody2D.velocity = velUp; } else if (Input.GetKey(Down)) { Vector3 velDown = rigidbody2D.velocity; velDown.y = walkSpeed*-1; rigidbody2D.velocity = velDown; } else if (Input.GetKey(Left)) { Vector3 velLeft = rigidbody2D.velocity; velLeft.x = walkSpeed*-1; rigidbody2D.velocity = velLeft; } else if (Input.GetKey(Right)) { Vector3 velRight = rigidbody2D.velocity; velRight.x = walkSpeed; rigidbody2D.velocity = velRight; } else { Vector3 velStop = rigidbody2D.velocity; velStop.x = 0; velStop.y = 0; rigidbody2D.velocity = velStop; } //rotation Vector3 mousePos = Input.mousePosition; Vector3 objectPos = Camera.main.WorldToScreenPoint (transform.position); mousePos.x = mousePos.x - objectPos.x; mousePos.y = mousePos.y - objectPos.y; float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg; transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle)); } ``` How can I get the movement to behave as I mentioned? With it moving diagonally like this makes the movement seem off. Any help is greatly appreciated. Thanks.