How to Create a Simple 2D Platformer Game in Unity
Content:
Unity is a powerful and popular game engine that allows you to create games for various platforms. In this tutorial, we will learn how to create a simple 2D platformer game in Unity. We will cover the following topics:
- Setting up the project and importing assets
- Creating the player and the enemies
- Adding physics and collision detection
- Implementing the user interface and the game logic
- Building and testing the game
Setting up the project and importing assets
First, we need to create a new project in Unity. Open Unity Hub and click on the New button. Give your project a name, such as “2D Platformer”, and select the 2D template. Click on the Create button to create the project.
Next, we need to import some assets that we will use for the game. You can download the assets from [this link] or use your own assets. To import the assets, go to Assets > Import Package > Custom Package and select the downloaded package. Click on the Import button to import the assets.
You should see a folder called “2D Platformer Assets” in your Project window. This folder contains the sprites, animations, sounds, and fonts that we will use for the game.
Creating the player and the enemies
Now, we need to create the player and the enemies for the game. To create the player, go to GameObject > 2D Object > Sprite and name it “Player”. Drag and drop the “Player” sprite from the assets folder to the Sprite Renderer component of the player object. You should see the player in the Scene view.
To make the player move, we need to add some components to the player object. Select the player object and click on the Add Component button. Add the following components:
- Rigidbody 2D: This component allows the player to be affected by physics and gravity. Set the Body Type to Dynamic and the Gravity Scale to 3.
- Box Collider 2D: This component allows the player to collide with other objects. Adjust the Size and Offset values to fit the player sprite.
- Animator: This component allows the player to have animations. Drag and drop the “Player” animator controller from the assets folder to the Controller slot of the animator component.
To create the enemies, we will follow a similar process. Create two new sprite objects and name them “Enemy1” and “Enemy2”. Drag and drop the “Enemy1” and “Enemy2” sprites from the assets folder to the Sprite Renderer components of the enemy objects. Add the Rigidbody 2D, Box Collider 2D, and Animator components to the enemy objects. Drag and drop the “Enemy1” and “Enemy2” animator controllers from the assets folder to the Controller slots of the animator components.
Adding physics and collision detection
To make the game more realistic and fun, we need to add some physics and collision detection to the game. We will use the Physics 2D and the Collision 2D components to achieve this.
To make the player jump, we need to add some code to the player object. Create a new C# script and name it “PlayerController”. Drag and drop the script to the player object. Double-click on the script to open it in Visual Studio. Replace the code with the following code:
using UnityEngine; public class PlayerController : MonoBehaviour { // Variables to store the components private Rigidbody2D rb; private Animator anim; // Variables to store the input values private float horizontal; private bool jump; // Variables to store the parameters public float speed = 5f; public float jumpForce = 10f; public LayerMask groundLayer; // Start is called before the first frame update void Start() { // Get the components rb = GetComponent<Rigidbody2D>(); anim = GetComponent<Animator>(); } // Update is called once per frame void Update() { // Get the input values horizontal = Input.GetAxis("Horizontal"); jump = Input.GetButtonDown("Jump"); // Flip the sprite according to the input direction if (horizontal < 0) { transform.localScale = new Vector3(-1, 1, 1); } else if (horizontal > 0) { transform.localScale = new Vector3(1, 1, 1); } // Set the animation parameters anim.SetFloat("Speed", Mathf.Abs(horizontal)); anim.SetBool("Jump", !IsGrounded()); } // FixedUpdate is called once per physics update void FixedUpdate() { // Move the player horizontally rb.velocity = new Vector2(horizontal * speed, rb.velocity.y); // Make the player jump if the input is pressed and the player is on the ground if (jump && IsGrounded()) { rb.AddForce(new Vector2(0, jumpForce), ForceMode2D.Impulse); } } // A method to check if the player is on the ground bool IsGrounded() { // Cast a ray downwards from the center of the player RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, 1f, groundLayer); // Return true if the ray hits something, false otherwise return hit.collider != null; } }
This code defines some variables to store the components, the input values, and the parameters. It also defines some methods to control the movement, the jumping, the flipping, and the animation of the player. Save the script and go back to Unity.
To make the enemies move, we need to add some code to the enemy objects. Create a new C# script and name it “EnemyController”. Drag and drop the script to the enemy objects. Double-click on the script to open it in Visual Studio. Replace the code with the following code:
using UnityEngine; public class EnemyController : MonoBehaviour { // Variables to store the components private Rigidbody2D rb; private Animator anim; // Variables to store the parameters public float speed = 3f; public float patrolDistance = 5f; // Variables to store the state private bool facingRight = true; private float initialPosition; // Start is called before the first frame update void Start() { // Get the components rb = GetComponent<Rigidbody2D>(); anim = GetComponent<Animator>(); // Get the initial position initialPosition = transform.position.x; } // Update is called once per frame void Update() { // Set the animation parameter anim.SetFloat("Speed", Mathf.Abs(rb.velocity.x)); } // FixedUpdate is called once per physics update void FixedUpdate() { // Move the enemy horizontally rb.velocity = new Vector2(speed, rb.velocity.y); // Flip the enemy if it reaches the patrol distance if (transform.position.x > initialPosition + patrolDistance && facingRight) { Flip(); } else if (transform.position.x < initialPosition - patrolDistance && !facingRight) { Flip(); } } // A method to flip the enemy void Flip() { // Toggle the facing direction facingRight = !facingRight; // Flip the sprite transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z); } }
This code defines some variables to store the components, the parameters, and the state. It also defines some methods to control the movement, the flipping, and the animation of the enemy. Save the script and go back to Unity.
To make the player and the enemies interact, we need to add some code to detect the collision between them. Create a new C# script and name it “CollisionController”. Drag and drop the script to the player object. Double-click on the script to open it in Visual Studio. Replace the code with the following code:
using UnityEngine; using UnityEngine.SceneManagement; public class CollisionController : MonoBehaviour { // A method to handle the collision with other objects private void OnCollisionEnter2D(Collision2D collision) { // If the player collides with an enemy if (collision.gameObject.CompareTag("Enemy")) { // Get the contact point ContactPoint2D contact = collision.GetContact(0); // If the player hits the enemy from above if (contact.normal.y > 0) { // Destroy the enemy Destroy(collision.gameObject); } else { // Restart the game SceneManager.LoadScene(SceneManager.GetActiveScene().name); } } } }
This code defines a method to handle the collision with other objects. It checks if the player collides with an enemy and determines the contact point. If the player hits the enemy from above, it destroys the enemy. Otherwise, it restarts the game. Save the script and go back to Unity.