# 2D topdown character controller

Hi I’m trying to make a 2D top down game. I have been trying to get my movement script to work but It has some bugs. It uses the WASD keys to move. The problem is when both W and A ( or W and D or D and S or A and S) get pressed I want the character to rotate 45 degrees so he is facing the correct Direction and move forward. I have managed this but there are a few bugs. When the W and A key is pressed the character has three times as much velocity when moving forward.
Can any one help me with this?

Heres my code

using UnityEngine;
using System.Collections;

public class Movement : MonoBehaviour {
//the speed that you want the object to go at
public float speed;
//this must be 2/3 of speed to even out the speed when two buttons are pressed
public float minusSpeed;

``````bool isUp = true;
bool isDown = false;
bool isRight = false;
bool isLeft = false;

void Update ()
{

if(isRight == true) {
transform.eulerAngles = new Vector3(0, 0, -90);
}

if(isLeft == true) {
transform.eulerAngles = new Vector3(0, 0, 90);
}

if(isUp == true){
transform.eulerAngles = new Vector3 (0, 0, 0);
}

if(isDown == true) {
transform.eulerAngles = new Vector3(0, 0, 180);
}

if(Input.GetKey(KeyCode.D)){
transform.Translate (Vector2.up * speed);
isRight = true;
isLeft = false;
isUp = false;
isDown = false;
}

if(Input.GetKey(KeyCode.A)){
transform.Translate (Vector2.up * speed);
isLeft = true;
isRight = false;
isUp = false;
isDown = false;
}

if(Input.GetKey(KeyCode.W)){
transform.Translate (Vector2.up * speed);
isLeft = false;
isRight = false;
isUp = true;
isDown = false;
}

if(Input.GetKey(KeyCode.S)){
transform.Translate (Vector2.up * speed);
isLeft = false;
isRight = false;
isUp = false;
isDown = true;
}

if(Input.GetKey(KeyCode.D)){
if(Input.GetKey(KeyCode.W)){
transform.eulerAngles = new Vector3(0, 0, -45);
transform.Translate (Vector2.up * speed);
isRight = false;
isLeft = false;
isUp = false;
}
}

if(Input.GetKey(KeyCode.D)){
if(Input.GetKey(KeyCode.S)){
transform.eulerAngles = new Vector3(0, 0, 225);
transform.Translate (Vector2.up * speed);
//Debug.Log(Vector2, speed);
isRight = false;
isLeft = false;
isUp = false;
}
}

if(Input.GetKey(KeyCode.A)){
if(Input.GetKey(KeyCode.W)){
transform.eulerAngles = new Vector3(0, 0, 45);
transform.Translate (Vector2.up * speed);
isRight = false;
isLeft = false;
isUp = false;
}
}
if(Input.GetKey(KeyCode.A)){
if(Input.GetKey(KeyCode.S)){
transform.eulerAngles = new Vector3(0, 0, 135);
transform.Translate (Vector2.up * speed);
isRight = false;
isLeft = false;
isUp = false;
}
}
}
``````

}

You shouldn’t use transform.translate to move your charachter. This basically is the same as a teleportation.

Use transform.velocity=new vector2(…);

For your magnitude problem: you are giving x and y the same magnitude when moving in diagonal as when moving along the axis.

Use new vector2(…).normalized to have a normal magnitude in every direction (square root of the squared sum of the elements is always equal to one)

Cheers

It is more easy, you must do a animator tutorial.

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

public class Player : MonoBehaviour {

private Animator anim;
public Vector3 startPosition;
public Vector2 speed = new Vector2(1,0);

void Start(){

startPosition = transform.position;
anim = GetComponent ();
}

void Update () {

float inputX = Input.GetAxis("Horizontal");
float inputY = Input.GetAxis ("Vertical");

anim.SetFloat("SpeedX",inputX);
anim.SetFloat("SpeedY",inputY);

Vector3 movement = new Vector3
(speed.x*inputX, speed.y*inputY,0);

movement*= Time.deltaTime;
transform.Translate(movement);
}

void FixedUpdate() {
float lastinputX = Input.GetAxis("Horizontal");
float lastinputY = Input.GetAxis("Vertical");

if (lastinputX !=0 || lastinputY !=0){
anim.SetBool("walking",true);

if (lastinputX>0){
anim.SetFloat("LastMoveX",1f);
}
else if (lastinputX<0){
anim.SetFloat("LastMoveX",-1f);
}else {
anim.SetFloat("LastMoveX",0f);
}

if (lastinputY>0){
anim.SetFloat("LastMoveY",1f);
}
else if (lastinputY<0){
anim.SetFloat("LastMoveY",-1f);

}else {
anim.SetFloat("LastMoveY",0f);
}

}else {
anim.SetBool("walking",false);
}
}
}
``````