[UNITY TUTORIAL] [BEGINNER] [MOVEMENT TUTORIAL]
This project provides a basic tutorial of Player movement in Unity Engine with scripting for movement in a specified direction and jumping from the ground along with a Finish/Death script for checking game progress. Good luck with starting your Game Development Journey.
Usually, a level design comprising of pixel art should be done in tilemap but for simplicity, normal sprite workflow is used for level design in this tutorial. Graphics assets and the complete Project files are linked below.
1. Open the Unity hub and create a new project. Select 2d from the left menu and rename your project to your desired one. Then press Start to build the project.
2. Now you can see the Unity Editor with an empty scene. Import the Graphics Asset folder to Unity by dragging the entire folder and dropping it to the Assets Panel. The first search for the “Tile Top 1080” image present in the “Platform folder 1” and change the pixels per unit to 1000 in the hierarchy. Do this step for each image before using it in the scene.
This is done to manage the overall size of the image and resize it according to the need. It is just the amount of pixels that can be accumulated in one unit cell. On increasing the Pixels per unit the image size decreases while making it more detailed and vice versa. As the units in Unity are arbitrary, Unity uses the number of pixels on a unit cell as a measure of the sprite imported.
3. Let’s create a 2d sprite by clicking the right mouse button in the Hierarchy and rename the Gameobject as “Ground”. Now replace the image of the sprite from the Sprite Renderer in the Inspector to the Ground image namely “Tile Top 1080” we have with us. Also, position it a bit lower so that player can stand over it. Add some more ground sprites and position it side by side to get enough space for our player to move.
You could duplicate the ground you have created at first just by selecting the ground game object from hierarchy and press CTRL+D. Now position each ground object side by side.
4. Now select all the Ground Gameobject and add a box collider to them so that any component can collide with them. Head over to Add component in the Inspector and search for “Box Collider 2d” as we are dealing with the 2d environment. Unity automatically snaps the box collider to the geometry of the sprite. However, you can edit that through the option “Edit Collider” available in the “Box Collider 2D” component if you have any irregular shapes which Unity might not properly mesh automatically.
5. Add another 2D sprite and change the sprite image to player graphics. Search for “Box Bot 1080” in the Character Folder and select it, change the pixels per unit to 1000 in the hierarchy. Place the Player above the Ground so that it can fall directly to the ground. Also, add “Box collider 2d” so that the player can collide with the ground and can stand over it. Adjust the box collider length if required. Now add “Rigidbody 2d” component to the player. This helps to implement all the physics related application to the desired object.
6. We have completed creating the Ground and the Player. It’s time to see our player in action !! Click on the Add component from the player inspector and Click the New Script. Rename the script to “Movement” and open with any code editor available with you.
If you are using Microsoft Visual Studio, You could notice some prebuilt line of code already available before you. The above three lines are known as headerfiles or the packages you need to import. After this, you can see the script name deriving from Monobehaviour, which we don’t need at this stage. There are two prebuilt functions already defined, The “Start Function” and the “Update Function”. The “Start Function” is responsible for all the operations defined in it to execute while the program starts for the first time. The “Update Function” is called on every frame and runs continuously which is heavily dependant on the frame rate of a PC. It is always preferred to do all the Physics related operation on the “FixedUpdate Function” because it will be executed exactly in sync with the physics engine itself, whereas “Update”, on the other hand, works independently of the physics engine and is restricted to frame rate as stated above. This can be beneficial if a user's frame rate were to drop but you need a certain calculation to keep executing like if you were updating a chat or voip client, you would want.
7. Now let’s start creating our movement script. First declare a reference to the rigidbody, speed of the movement, jump force and a boolean that detects whether a player should jump.
8. Now we have to implement a method so that we can jump only when we press a certain key. Let’s check for this logic in the “Update Function”, If we press down the “W” button, we enable the jump boolean to true and change back to false if we aren’t.
9. Again for the boolean jump state in the “FixedUpdate” as we have discussed above to use it for physics-related operations. If the jump is true let’s add some upward force to the player by first referencing the player then implementing the operation. That is player.AddForce(vector2). The Vector 2 here is responsible for storing the direction of the force to act upon and we can further multiply with some magnitude. So our code becomes, player.AddForce(player.velocity.x, jumpspeed).
We keep player.velocity.x in the x place, as we don’t want to restrict the players movement to any specific value and we don’t want to add any force towards x direction. Therefore we keep player.velocity.x, so that the force will only act upon y direction independent of any x position of the player.
10. Lastly, we have to move the player in a particular direction. We can do this by giving velocity to the player. We just have to reference the player and add a velocity. The velocity also takes a Vector2 to act force upon a certain object. Now we have to move along the x direction so we have to declare a new Vector2 and assign the magnitude * direction * time.deltatime in the x place and keep the y place same as player.velocity.y because we don’t want to restrict the player movement on y direction.
Here we use time.deltatime because it helps to manage the same speed no matter what the frame rate is, Therefore you will not experience any difference in movement if you play your game in high FPS and computer running in Low FPS. The “Input.GetAxisRaw(“Horizontal”) helps in getting the direction of the player which is encoded with the horizontal key movement namely a and d. It’s a floating number with a minimum value of -1 and a maximum value of 1 where the sign depicts the direction of the movement. On pressing the "A" key down the floating number reaches gradually to -1 and hence the player moves left and vice versa. We have used for smooth movement and we can still use the “GetAxis” instead if we don’t require any smoothing.
11. So Far we have completed the movement script of the player. Now save the code and get back to Unity editor. It’s time to reference the object that is needed by the “Movement” Script. Drag the “Rigidbody 2d” component from the inspector and drop it down on the empty slot of “Movement” Script. Bump up the speed to 400 and jump speed to 300.
12. Press the Play button and start moving the player by pressing the a and d key down. Press the w key for the jump. You might notice a slopy jump when you try to move the player and jump at the same time. You can improve the jumping by increasing the “Gravity scale” to 3 and increasing the jumpspeed to 600. Also, check the “Freeze z” on the constraint option to restrict the rotation of the player. Now you have a better-polished movement. Let’s head towards Level Design and Level-up feature.
13. Arrange the level by placing some “Crates”, obstacles like “Spikes” and a “Finish line”. Also, add “Box Collider 2d” to each of the elements and adjust the size if required. Now we have to make our player die if the player touches the spike. We can simply do it by adding a tag to a spike game object. Click the Spike game object from the hierarchy and select the tag drop-down menu from the inspector to add a tag. Add a tag namely spikes and assign it by pressing the spike game object again and checking the spikes tag from the Tag option present over the inspector.
14. Now if the player collides it will destroy the gameobject and print the message “Player died”.
Head back to the Visual Studio, and add few lines of code in “OnCollisionEnter2d” to check the collision state of the player. We will check if the collision.collider.tag==”spikes” then “Destroy(gameobject)” and “Debug.log(“Player Died”)”.
Oncollisionenter2d helps in determining all the collisions acting upon an object.] Save your code and get back to UNITY. Don’t forget to assign the tag “spikes” in the Spikes Gameobject. Hit Play and now you will able to make your player die if it touches the spikes.
15. Repeat the same method by adding a tag to the “Finish Line” and then checking whether the player collides with it or not while printing a message “Game Won”. And Yes !! You have finally completed your first game!!
Congratulations on completing your first step towards the vast ocean of Game Development. Now that you've stepped into the ocean of Game Development its time to get deeper because this is just the beginning. More beginner tutorials coming soon in this beginner series. Stay tuned. The Project files are linked below.
Project Files - Box Bot - Tutorial 1 Project Files
Graphics Assets - Box Bot Graphics Assets