Rotating a Character in the Direction of Movement - Unity Game Development Tutorial
In this Unity game development tutorial we're going to look at how we can rotate an object so that it faces the direction it’s moving in.
You can either watch the video version below or continue reading for written instructions.
Right, let's get started by creating a new 3D project in Unity Hub.
We'll add a Plane to represent our floor by clicking the plus button on the Hierarchy and selecting 3D Object->Plane.
We'll set the scale of the Plane to ten on the X axis and ten on the Z axis.
Next, we'll create a material to change the colour of the floor. To do this, we'll click the plus button on the Project panel and select Material. We'll name this material 'Floor'.
We'll then click on the box next to Albedo in the Inspector panel, and choose a green colour.
We can now drag the material on to the Plane to assign it.
We now need a character to move around our scene. For this we'll head over to the Asset Store by selecting Window->Asset Store from the main menu. We'll then search for 'RPG Monster DUO', and we'll download and import this asset.
Now we've got all the assets we need, we'll return to the Scene view.
Next, we’ll add our character into the scene. In the Project panel, we'll navigate to Assets->RPG Monster Duo Polyart->Prefabs, and then we'll drag the SlimePBR prefab into the scene.
We'll reset the Transform to centre the character in our scene.
We'll also turn off the animator component as we won't be looking at animations in this video.
To improve the lighting in our scene we'll select Window->Rendering->Lighting Settings from the main menu, and then we'll tick the 'Auto Generate' check box.
Now we have everything setup in our scene, the next thing we need to do is create a script to make our character move and rotate.
To do this, we'll click on 'Add Component' in the Inspector panel and add a new script component, which we'll call PlayerMovement
We'll double click the script to open it in Visual Studio and change it to match the following.
using UnityEngine; public class PlayerMovement : MonoBehaviour { public float speed; void Update() { float horizontalInput = Input.GetAxis("Horizontal"); float verticalInput = Input.GetAxis("Vertical"); Vector3 movementDirection = new Vector3(horizontalInput, 0, verticalInput); movementDirection.Normalize(); transform.Translate(movementDirection * speed * Time.deltaTime, Space.World); } }
In our Update method, we're getting the player input on the horizontal axis and assigning it to a variable. We're also doing the same for the vertical axis.
We're then using these input values to create a three dimensional vector for the direction we want the character to move. We're setting the direction on the X axis to our horizontal input, the direction on the Y axis to zero as we don't want the character to move up and down, and the direction on the Z axis to our vertical input.
We're then normalising the direction vector to ensure it has a magnitude of one.
Next, we're changing the position of the character based on the movement direction by accessing the object's Transform and using the Translate method to move it in the direction we want.
We want to be able to control how fast the character moves, so we've created a public variable for the speed. We're then multiplying the direction by this speed. We're also multiplying by Time.deltaTime to ensure it moves at the same speed regardless of our framerate.
Finally, we're also specifying that we are moving the character relative to the World.
Let's save the script and switch back to Unity.
We'll set the speed to five in the Inspector panel.
Let's press play to try this out.
We can now press the arrow keys to move the character around the scene.
The character moves but it doesn't turn to face the direction it's moving yet.
Let's stop the game and make the following changes to the script to fix this.
using UnityEngine; public class PlayerMovement : MonoBehaviour { public float speed; void Update() { float horizontalInput = Input.GetAxis("Horizontal"); float verticalInput = Input.GetAxis("Vertical"); Vector3 movementDirection = new Vector3(horizontalInput, 0, verticalInput); movementDirection.Normalize(); transform.Translate(movementDirection * speed * Time.deltaTime, Space.World); if (movementDirection != Vector3.zero) { transform.forward = movementDirection; } } }
First of all, we're checking if the character is moving by checking that the movement direction is not zero.
If it is moving, we want the character to rotate to face the direction it's moving. To do this, we're setting the forward direction of the transform to the movement direction.
Let's save the script and switch back to Unity and press play to try this out.
The character now turns immediately to face the direction of movement. While this is much better, the instant rotation feels a bit unnatural. We can make the rotation look much smother by having the character rotate to the desired direction over a period of time.
Let's stop the game and make the following changes to the script to do this.
using UnityEngine; public class PlayerMovement : MonoBehaviour { public float speed; public float rotationSpeed; void Update() { float horizontalInput = Input.GetAxis("Horizontal"); float verticalInput = Input.GetAxis("Vertical"); Vector3 movementDirection = new Vector3(horizontalInput, 0, verticalInput); movementDirection.Normalize(); transform.Translate(movementDirection * speed * Time.deltaTime, Space.World); if (movementDirection != Vector3.zero) { Quaternion toRotation = Quaternion.LookRotation(movementDirection, Vector3.up); transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime); } } }
First of all, we've deleted the line where we set the forward direction.
We want to make the character rotate towards the movement direction at a specific rate, so we've added a public variable for the rotation speed.
Next, we need to get the desired destination rotation. We're storing this in a Quaternion variable which is a type specifically for storing rotations. We're then using the Quaternion LookRotation method to create a rotation looking in the desired direction. We're setting the forward direction to the movement direction, and we're setting the up direction to the Y axis using the Vector3.up property.
We're then using the Quaternion RotateTowards method to rotate from our current rotation towards the desired direction. We're using our rotation speed variable to control how quickly the character rotates, remembering to multiply by Time.deltaTime.
Let's save the script and switch back to Unity.
We'll set the rotation speed to 720 so that the character changes direction quickly.
Let's press play to try this out.
Now when we move, the rotation is much smoother and looks a lot more natural!
That covers everything for this tutorial. We hope that you found it useful. Please leave any questions or feedback in the comments below, and don't forget to subscribe to get notified when we publish our next post.
Thanks.
This is just clean and clear, congrats!
ReplyDeleteClear and on point. Thank You.
ReplyDeletehow can I make it turn by the direction the camera is facing? I can't get it to work :( cause I just want to make a "normal" movement system you find in games like Zelda or GTA where the character can move around freely but when you turn the camera to somewhere the front is where the camera shows...
ReplyDeleteI know I'm a noob at this :I
How can I make it jump? Can you please give me any clue?
ReplyDeleteImpressive and powerful suggestion by the author of this blog are really helpful to me.
ReplyDeletergb to greyscale