Generally with the questions "How game X made Y" it is better to contact the developers themselves. And not because someone is “too lazy” to answer such questions, but simply because it is often quite difficult to recreate something from another 1v1 game.
Surely this can be done in another way, but I decided to go through 2 stages:
- character rotation depending on input
- Moving a character through
transform.forward , good character in this game always moves only face forward
Data input
Everything is as simple as possible and does not differ from the variant in question, but I write down the whole thing in a vector, in order to get corners and other necessary things through it:
private Vector3 moveVector; ... void HandleInput() { moveVector.x = Input.GetAxis("Horizontal"); moveVector.z = Input.GetAxis("Vertical"); }
Rotation
It would seem you can just use
transform.Rotate(Vector3.up, Vector3.Angle(transform.forward, moveVector));
But Vector3.Angle returns the smallest angle between the vectors, i.e. from 0 to 180, which leads to these results when rotating by an angle from 0 to 360:

One of the ways out of this situation is to write your own function for determining the angle between vectors for a range of angles [0..360]:
float Angle360(Vector3 from, Vector3 to, Vector3 right) { float angle = Vector3.Angle(from, to); return (Vector3.Angle(right, to) > 90f) ? 360f - angle : angle; }
This function is very simple to find in Google - I do not want to overload the question with its explanation.
And then we apply the whole thing in Update :
void Update () { HandleInput(); transform.Rotate(Vector3.up, Angle360(transform.forward, moveVector, transform.right)); }
And we get the rotation we almost need:

Move
Everything is almost elementary: it uses Transform.Translate , not forgetting to add a variable for speed:
public float speed = 2f; ... transform.Translate(transform.forward * speed * Time.deltaTime, Space.World);
This code will constantly move the object in the direction of its local "straight." But we want to move it only when the user enters.
The logical way out is to use the moveVector vector moveVector , having previously normalized it, in order to get a value in the range [0..1]:
transform.Translate( moveVector.normalized.sqrMagnitude * transform.forward * speed * Time.deltaTime, Space.World );
In this case, you can use the module square simply because the module square will always be either 0 or 1 , and sqrt(1) == 1/-1 , sqrt(0) == 0 . -1 for obvious reasons, we are not worried.
But purely on sensations - I did not measure the results, it's easier to do without this module at all and do this:
float Moves() { if(moveVector.x != 0 || moveVector.z != 0) { return 1f; } else { return 0f; } }
It is worth noting that this method will always produce a motion vector 1. If the game supports gamepads, where joysticks can output values along both [0..1] axes, it is better to use a vector module.
And substituting the result of this method in Translate .
In the end, we got some such component:
public class OvercookedLikeMovement : MonoBehaviour { public float speed = 2f; private Vector3 moveVector; void Update () { HandleInput(); transform.Rotate(Vector3.up, Angle360(transform.forward, moveVector, transform.right)); transform.Translate( Moves() * transform.forward * speed * Time.deltaTime, Space.World ); } void HandleInput() { moveVector.x = Input.GetAxis("Horizontal"); moveVector.z = Input.GetAxis("Vertical"); } float Moves() { if(moveVector.x != 0 || moveVector.z != 0) return 1f; else return 0f; } float Angle360(Vector3 from, Vector3 to, Vector3 right) { float angle = Vector3.Angle(from, to); return (Vector3.Angle(right, to) > 90f) ? 360f - angle : angle; } }
Result in Unity:

PS
It is seen that the object sometimes moves jerky. The reason for this is a sharp change in the angle of rotation of the object, this is not a bug, but the logical result of the code is higher and not done without interpolation.
What would I do if I were you?
I would look in the direction of Tween engines for Unity, with which you can smooth the whole thing and make it more natural, or something. But the result at the moment, as for me, is very similar to OverCooked.