character and camera not moving in the same speed

the two scripts below do the similar things,
get the key press and calculation the direction after the direction calculated, they multiple with the same speed, say 0.05f,
while the character and the camera, do not move at the same speed, and the character move faster than the camera.
if i rotate the camera a bit and move the character, the character move even faster than camera.
i believe there are something wrong in the variable direction, i would like to like how can i fix it so that both of them can move at the same speed in every direction.
Thank you.

character movement script:

    animation.CrossFade("moving");
direction = Vector3.zero;
myposition= transform.position;

if(Input.GetKey("i")) {
direction += Vector3.forward;
currentkeydown=true;
}
if(Input.GetKey("k")){
direction += Vector3.back;
currentkeydown=true;
}

if(Input.GetKey("j")){
direction += Vector3.left;
currentkeydown=true;
}

if(Input.GetKey("l")){
direction += Vector3.right;
currentkeydown=true;
}

//if two key press
if(Mathf.Abs(direction.x)+Mathf.Abs(direction.y)+Mathf.Abs(direction.z)>1){
direction.x/=2;
direction.y/=2;
direction.z/=2;
}

//if direction change
if (direction != Vector3.zero) {
direction = Quaternion.Euler(0.0f, Camera.main.transform.localEulerAngles.y, 0.0f) * direction;
transform.rotation = Quaternion.LookRotation(direction);
}

if(currentkeydown){
transform.position+=direction*speed;
}


and camera script

if(Input.GetKey("i")) {

direction += Vector3.forward;
currentkeydown=true;
}

if(Input.GetKey("k")){
direction += Vector3.back;
currentkeydown=true;
}

if(Input.GetKey("j")){
direction += Vector3.left;
currentkeydown=true;
}

if(Input.GetKey("l")){
direction += Vector3.right;
currentkeydown=true;
}

if(Input.GetKey("u")){
transform.RotateAround(player.transform.position,Vector3.up,-2f);
}
if(Input.GetKey("o")){
transform.RotateAround(player.transform.position,Vector3.up,2f);
}

direction = transform.TransformDirection(direction);
direction.y = 0;
if(currentkeydown){
if(Mathf.Abs(direction.x)+Mathf.Abs(direction.y)+Mathf.Abs(direction.z)>1){
direction.x/=2;
direction.y/=2;
direction.z/=2;
}
transform.position+=direction*speed;
}


Normalize the direction component after you get your inputs and get rid of this nonsense:

direction.x/=2;
direction.y/=2;
direction.z/=2;


Then multiply the normalized direction value by speed to get the correct movement vector.

• is that mean i should use something like min-max normalization for the both vector.x y z? i divide the xyz by 2 because if two key is pressed, the vector will be sum of two direction, like up and left, the vector will become (1 0 1), then if i multiply it by speed, it will run faster than single direction, isn't it? – brian661 Dec 29 '13 at 18:14
• Nope, you normalize each vector. Nothing with min-max. – MichaelHouse Dec 29 '13 at 18:15

Maybe it is a point of view opinion but it seems you should use another approach :

1. If you have no plans on making your camera track another object then you should make it a child of your object (i do think it is not the good answer but i think it's still better than moving two objects separately when you want them to be synched)
2. If you need your camera to be versatile you should make it completely separated from input for it's position and input relative only for it's rotation.

Good tools for that is :

Making your cam position relative to a transform :

cam.position = object.position + localpos
//Calculate localpos using
cam.RotateAround(object.position,Vector3.Up,input.GetAxis("Horizontal"))
//or something similar


this should already make your code easyer to maintain and it could allow you to switch between targets painlessly

EDIT: And to stress it even more as Byte56 stated : Get rid of all the useless stuff