2D Platformer Game Basics

Implement player controller, camera tracking, and scene transitions for a 2D platformer game in Unity

Learn the essential scripts for creating a 2D platformer game in Unity. We'll implement basic game mechanics including player movement, jumping, camera tracking, and scene transitions.


Game Structure

A 2D platformer game consists of three core scripts:

Script Role
PlayerController Player movement, jumping, animation, collision handling
CameraController Camera that follows the player
ClearManager Game clear scene management

PlayerController - Player Controller

The core script that controls player movement, jumping, and animation.

Complete Code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class PlayerController : MonoBehaviour
{
    Rigidbody2D rb;
    Animator animator;
    float jumpForce = 680.0f;
    float walkForce = 30.0f;
    float maxWalkSpeed = 2.0f;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
    }

    void Update()
    {
        // Jump
        if (Input.GetKeyDown(KeyCode.Space) && rb.velocity.y == 0)
        {
            rb.AddForce(transform.up * jumpForce);
            animator.SetTrigger("Jump");
        }

        // Left/Right movement input
        int key = 0;
        if (Input.GetKey(KeyCode.RightArrow)) key = 1;
        if (Input.GetKey(KeyCode.LeftArrow)) key = -1;

        // Player speed
        float speedx = Mathf.Abs(rb.velocity.x);

        // Max speed limit
        if (speedx < maxWalkSpeed)
        {
            rb.AddForce(transform.right * key * walkForce);
        }

        // Direction change
        if (key != 0)
        {
            transform.localScale = new Vector3(key, 1, 1);
        }

        // Animation speed adjustment
        animator.speed = speedx / 2.0f;

        // Restart game if out of screen
        if (transform.position.x < -3.5f || transform.position.x > 3.5f || transform.position.y < -10f)
        {
            SceneManager.LoadScene("GameScene");
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        Debug.Log("OnTriggerEnter2D: " + collision.gameObject.name);
        SceneManager.LoadScene("ClearScene");
    }
}

Key Concepts Explained

1. Component References

Rigidbody2D rb;
Animator animator;

void Start()
{
    rb = GetComponent<Rigidbody2D>();
    animator = GetComponent<Animator>();
}
  • Rigidbody2D: Movement and collision handling through physics engine
  • Animator: Sprite animation control
  • Get component references in Start()

2. Jump Implementation

if (Input.GetKeyDown(KeyCode.Space) && rb.velocity.y == 0)
{
    rb.AddForce(transform.up * jumpForce);
    animator.SetTrigger("Jump");
}
  • Input.GetKeyDown(): Executes only once when key is pressed
  • rb.velocity.y == 0: Only jump when on ground (prevents double jump)
  • AddForce(): Apply physical force to jump
  • SetTrigger(): Trigger jump animation

3. Horizontal Movement

int key = 0;
if (Input.GetKey(KeyCode.RightArrow)) key = 1;
if (Input.GetKey(KeyCode.LeftArrow)) key = -1;

float speedx = Mathf.Abs(rb.velocity.x);

if (speedx < maxWalkSpeed)
{
    rb.AddForce(transform.right * key * walkForce);
}
  • Input.GetKey(): Executes continuously while key is held
  • maxWalkSpeed: Speed limit for natural movement
  • AddForce(): Physics-based movement for smooth acceleration/deceleration

4. Direction Change (Using LocalScale)

if (key != 0)
{
    transform.localScale = new Vector3(key, 1, 1);
}
  • Set localScale.x to 1 or -1 to flip sprite horizontally
  • Using localScale instead of flipX also flips child objects

Tip: SpriteRenderer.flipX only flips the sprite, while localScale flips colliders and child objects as well.

5. Animation Speed Control

animator.speed = speedx / 2.0f;
  • Adjust animation speed proportional to player movement speed
  • Animation stops when stationary, speeds up when moving fast

6. Screen Boundary Detection

if (transform.position.x < -3.5f || transform.position.x > 3.5f || transform.position.y < -10f)
{
    SceneManager.LoadScene("GameScene");
}
  • Restart game when player goes off screen
  • Check left, right, and bottom boundaries

7. Trigger Collision Detection

private void OnTriggerEnter2D(Collider2D collision)
{
    SceneManager.LoadScene("ClearScene");
}
  • Place a collider with Is Trigger checked at the goal point
  • Transition to clear scene when player reaches the goal

CameraController - Camera Tracking

A camera script that follows the player's Y-axis position.

Complete Code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour
{
    public GameObject player;

    void Update()
    {
        Vector3 playerPos = player.transform.position;
        transform.position = new Vector3(transform.position.x, playerPos.y, transform.position.z);
    }
}

Key Concepts Explained

Public Variable for Player Reference

public GameObject player;
  • Drag and connect player object in Inspector
  • public declaration makes it configurable in Inspector

Y-Axis Only Tracking

Vector3 playerPos = player.transform.position;
transform.position = new Vector3(transform.position.x, playerPos.y, transform.position.z);
  • Maintain camera's original X and Z position
  • Only Y-axis follows player position
  • Suitable for vertical scrolling platformers

Extension Tip: Use playerPos.x to also track X-axis, and use Vector3.Lerp() for smooth tracking.

Smooth Camera Tracking (Improved Version)

public class CameraController : MonoBehaviour
{
    public GameObject player;
    public float smoothSpeed = 5.0f;

    void LateUpdate()
    {
        Vector3 targetPos = new Vector3(transform.position.x, player.transform.position.y, transform.position.z);
        transform.position = Vector3.Lerp(transform.position, targetPos, smoothSpeed * Time.deltaTime);
    }
}
  • LateUpdate(): Move camera after player movement (executes after Update)
  • Vector3.Lerp(): Smooth interpolation for natural camera movement

ClearManager - Clear Scene Management

A script that handles game restart after clearing.

Complete Code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class ClearManager : MonoBehaviour
{
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            SceneManager.LoadScene("GameScene");
        }
    }
}

Key Concepts Explained

Mouse Click Detection

if (Input.GetMouseButtonDown(0))
{
    SceneManager.LoadScene("GameScene");
}
  • Input.GetMouseButtonDown(0): Left mouse button click
  • Return to game scene when clicking on clear screen

Build Settings Configuration

To use scene transitions, you must add scenes in File > Build Settings:

  1. GameScene - Main game scene
  2. ClearScene - Clear screen scene

Collision Detection Callbacks Summary

Callback functions used for Unity 2D collision detection:

Callback Function Description
OnCollisionEnter2D Physics collision started
OnCollisionStay2D Physics collision ongoing
OnCollisionExit2D Physics collision ended
OnTriggerEnter2D Trigger collision started
OnTriggerStay2D Trigger collision ongoing
OnTriggerExit2D Trigger collision ended

Collision vs Trigger: Collision involves physical interaction (pushing), Trigger only detects passing through.


Unity Setup Checklist

Player Object

  • Add Rigidbody2D component
  • Add Collider2D component (BoxCollider2D or CapsuleCollider2D)
  • Add Animator component (if using animation)
  • Add PlayerController script

Camera Object

  • Add CameraController script
  • Connect Player object to player variable in Inspector

Goal Object (Goal Point)

  • Add Collider2D component
  • Check Is Trigger

Build Settings

  • Add GameScene
  • Add ClearScene

Summary

Item Content
Player Movement Physics-based movement with Rigidbody2D.AddForce()
Jump AddForce(transform.up * jumpForce), only when grounded
Direction Change Set localScale.x to 1 or -1
Camera Tracking Follow player's Y-axis position only
Scene Transition SceneManager.LoadScene("SceneName")
Trigger Detection Use OnTriggerEnter2D() callback

By combining these three scripts, you can implement the core mechanics of a basic 2D platformer game.


← Back to Contents