Project Setup & the Player Controller
A platformer starts with the one thing every level depends on: a player that can move and jump reliably. In 2D Unity, that means Rigidbody2D and a ground check.
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed = 6f;
public float jumpForce = 12f;
public Transform groundCheck;
public LayerMask groundLayer;
Rigidbody2D rb;
bool isGrounded;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
isGrounded = Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
float move = Input.GetAxisRaw("Horizontal");
rb.linearVelocity = new Vector2(move * moveSpeed, rb.linearVelocity.y);
if (isGrounded && Input.GetButtonDown("Jump"))
{
rb.linearVelocity = new Vector2(rb.linearVelocity.x, jumpForce);
}
}
}
The pieces
Rigidbody2D(not the 3DRigidbody) handles gravity and movement for 2D games, set its Body Type toDynamicin the Inspector.Physics2D.OverlapCircle(point, radius, layerMask)checks whether any collider ongroundLayeroverlaps a small circle, a cheap, reliable way to ask "is the player standing on something?" without relying on fragile collision-event timing.groundCheckis an empty child GameObject positioned at the player's feet, purely there to give the overlap circle a position to check from.Input.GetAxisRaw(unlikeGetAxis) returns exactly -1, 0, or 1 with no smoothing, snappier and more predictable for platformer movement.- Only jump when
isGroundedis true, otherwise the player could jump endlessly in mid-air.
TIP
Put ground and platform tiles on their own Layer (e.g. "Ground"), and set groundLayer to only that layer in the Inspector. Otherwise OverlapCircle might count the player's own collider or an enemy standing nearby as "ground."