In general, everything is simple. You complicate things too much.
At a minimum, the obvious disadvantages are:
- When you press D you, for some reason, look at
PosZ , which is obviously responsible for the movement along the Z axis, which, in turn, is responsible for moving forward / backward. See the picture below:

Always remember: Z axis - forward / backward, X axis - left / right, Y axis - up / down.
- Further, for some reason, you use gravity to move aside. Although it should only affect the upward movement. When you press D, for some reason you are accounting
hero.transform.position.y*-gravity - When moving on the A key, for some
PosZ add it to PosZ and PosZ * Time.deltaTime, and then again when applying the parameters, multiply by delta hero.Move(directionA * Time.deltaTime); that surely changes the value not the way you want. Time.deltaTime enough to apply to the end operator in this case, so as not to depend on the frame rate. The rest is unnecessary, I think.
In general, in its simplest form, the movement due to CharacterController (I see the Move method, apparently from it) will look like this:
public float speed = 6.0F; public float gravity = 20.0F; public CharacterController hero; // public float jumpSpeed = 8.0F; // раскомментировать для прыжка void Start() { hero = GetComponent<CharacterController>(); } void Update() { Vector3 moveDirection = Vector3.zero; if (hero.isGrounded) { moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); moveDirection = transform.TransformDirection(moveDirection); moveDirection *= speed; // раскоментировать для прыжка // if (Input.GetButton("Jump")) // moveDirection.y = jumpSpeed; } moveDirection.y -= gravity * Time.deltaTime; hero.Move(moveDirection * Time.deltaTime); }
Here, Input.GetAxis("Horizontal") and Input.GetAxis("Vertical") are the names of the movement axes. By default they are called that way. And by default Horizontal - buttons A and D , Vertical (despite the name) - buttons W and S. All this can be viewed in the settings Edit → Project Settings → Input

These values return the unit Vector3 depending on the motion .... If left: (-1, 0, 0), to the right - (1, 0, 0), up (forward) - (0, 0, 1), down ( back) - (0, 0, -1).
As a result, due to these axes, we determine the motion vector and then multiply this vector by the speed and Time.deltaTime and apply this value in hero.Move .
As for gravity, we apply it, respectively, only on the vector Y: moveDirection.y -= gravity * Time.deltaTime; . No more.
Further.
About the keys WASD . Here everything is the same. It is necessary to determine the direction of movement, through the unit vector, and then apply the speed and deltaTime and throw it all into Move.
public float speed = 6.0F; public float gravity = 20.0F; public CharacterController hero; void Start() { hero = GetComponent<CharacterController>(); } void Update() { if (Input.GetKey(KeyCode.W)) { moveDirection = Vector3.forward; } if (Input.GetKey(KeyCode.S)) { moveDirection = -Vector3.forward; } if (Input.GetKey(KeyCode.A)) { moveDirection = -Vector3.right; } if (Input.GetKey(KeyCode.D)) { moveDirection = Vector3.right; } moveDirection *= speed; moveDirection.y -= gravity * Time.deltaTime; hero.Move(moveDirection * Time.deltaTime); }
The code is almost identical to the top. Only instead of Input.GetAxis("Horizontal") and Input.GetAxis("Vertical") we take the ready values of the vector fields in Unity. It turns out:
Vector3.forward = (0, 0, 1) -Vector3.forward = (0, 0, -1) Vector3.right = (1, 0, 0) -Vector3.right = (-1, 0, 0)
The only thing is, the object will move strictly to the side or forward / back. If the combination of button combinations to the side + up / down is necessary for the object to move diagonally, then in moveDirection it will be necessary to operate with coordinates:
if (Input.GetKey(KeyCode.W)) { moveDirection.z = Vector3.forward.z; } if (Input.GetKey(KeyCode.S)) { moveDirection.z = -Vector3.forward.z; } if (Input.GetKey(KeyCode.A)) { moveDirection.x = -Vector3.right.x; } if (Input.GetKey(KeyCode.D)) { moveDirection.x = Vector3.right.x; }
Everything else is unchanged .
I hope everything is clear.
The rest of its conditions, in the form lastPressedDTimeA = Time.time; and what you need, I think, add it yourself ... it does not affect the logic of movement (as long as you do not want to do this).
wasdkeys or something else? If a simple movement, then you are too wise ........ by the way should an object walk diagonally if for example wa or wd or sd or sa are clamped? or strictly straight? - Alexey Shimansky