The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →By the end of this tutorial, you will have a small, testable 2D platformer prototype in Unity 6.x: a placeholder player that can run left and right, jump only while grounded, land on platforms, and remain visible as the camera follows it.
This is deliberately not a complete game. There will be no enemies, combat, collectibles, menus, save system, or polished art yet. The first milestone is proving that the core loop works. The instructions and code below target Unity 6.1, documented by Unity as internal version 6000.1. Inspector labels, package versions, and menu locations can change in later releases.
As an Amazon Associate I earn from qualifying purchases.
What you are building
A platformer is a genre rather than one fixed technical template. A physics-driven platformer, precision platformer, auto-runner, and character-controller-heavy game may all require different movement systems.
This beginning uses the simplest useful target:
- A side-view level
- One player character
- Keyboard left/right movement
- Grounded jumping
- Static platforms
- An orthographic follow camera
Unity is a suitable choice for this prototype because its 2D workflow includes sprites, Tilemaps, SpriteShape, 2D physics, animation, and related tools. Unity’s 2D workflow documentation specifically covers the systems commonly used for side-on platformers.
#1 Best Overall
What you need before starting
- Unity Hub
- A current Unity 6.x editor. This article uses Unity 6.1 / 6000.1.
- A C# editor such as Visual Studio or another editor supported by Unity.
- Basic familiarity with files, folders, and keyboard input.
- Optional version control. Unity’s version-control guidance is worth considering once the project contains scripts and scenes you cannot easily recreate.
Use the same editor version as the tutorial where possible. Older tutorials often use the legacy Input Manager, older Rigidbody2D property names, or different package workflows.
Do you need to pay for Unity?
For a beginner or eligible small team, Unity Personal is the natural starting point. Unity’s current plan information says Personal is available to individuals and small organizations below its stated revenue and funding threshold. Check the official eligibility page before publishing a commercial project, because thresholds, regions, taxes, and plan terms can change.
Unity Pro is not necessary for this prototype. Unity currently lists Pro at $210 per month or $2,310 per year in the United States before applicable regional adjustments, but the plan is intended for professional use and has separate requirements. A Unity subscription alone also does not grant access to closed-console platforms; platform-holder approval and additional requirements apply.
Recommended Free Tools
Create the 2D project
- Open Unity Hub.
- Install the chosen Unity 6.x editor.
- Choose New project.
- Select the 2D template.
- Name the project
PlatformerPrototype. - Choose a location and create the project.
- Save the initial scene immediately with File > Save As.
- Create a scene named
Level_01.
The 2D template includes many of the packages used for 2D development. Unity’s 2D setup documentation describes the template and related systems, including Tilemap and 2D animation tools.
Organize the project
In the Project window, create this structure:
Assets/
Art/
Characters/
Environment/
Audio/
Materials/
Prefabs/
Scenes/
Scripts/
Player/
World/
Tilemaps/
UI/
Save scenes with descriptive names, create a Player prefab once the initial GameObject works, and keep scripts focused. Input, movement, animation, health, combat, and camera control should not become one giant controller file.
Build a temporary level first
Use plain shapes or a temporary sprite. Do not begin by importing a polished character sheet or buying an art pack. Art import settings, animation frames, sorting layers, and asset licenses can distract from the systems that need testing.
Rank #2
Make a floor
- Create a new empty GameObject and name it
Ground. - Add a
SpriteRenderer, or use a simple visible placeholder. - Add a
BoxCollider2D. - Create a layer named Ground and assign the object to it.
- Duplicate the object several times to make ledges and steps.
For the first test, individual Sprite GameObjects are easier than a Tilemap: each platform has an obvious collider and can be inspected separately. Later, use a Grid and Tilemap for larger, reusable levels.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Create the player
- Create a visible placeholder sprite or simple square and name it
Player. - Add a
Rigidbody2D. - Add a
CapsuleCollider2Dor narrowBoxCollider2D. - Set the Rigidbody2D body type to Dynamic.
- Freeze rotation on the Z axis under Constraints.
- Leave mass and drag near their defaults until movement works.
- Place the player above the floor.
Each component has a different responsibility:
- Transform: position, rotation, and scale.
- Rigidbody2D: participation in Unity’s 2D physics simulation, including gravity and velocity.
- Collider2D: the shape used for collision.
- SpriteRenderer: the visible image.
- Animator: later, idle, run, jump, and fall animation states.
- Script: input, movement decisions, and grounded state.
Do not move a physics-controlled player by repeatedly assigning transform.position. Unity’s Rigidbody2D documentation explains why physics objects should be moved through their Rigidbody2D. Mixing Transform movement with Rigidbody2D movement can cause tunneling, jitter, and unreliable collision results.
Choose the collider carefully
A CapsuleCollider2D is forgiving around corners; a BoxCollider2D is easy to inspect. Avoid a detailed PolygonCollider2D for a simple character unless the artwork genuinely requires it.
Check that the collider does not extend noticeably below the feet, is not wider than the sprite, and is not accidentally attached to the wrong object. A character collider that is too large can create invisible wall collisions or make the player appear to float.
Add keyboard controls with the Input System
The recommended approach is Unity’s Input System rather than legacy calls such as Input.GetAxis. Unity’s official Player character and movement course uses the Input System and frame-rate-independent 2D movement.
Create the actions
- In the Project window, choose Create > Input Actions.
- Name the asset
PlayerControls. - Open it.
- Create an action map named
Player. - Create a
Moveaction with type Value and control type Vector2. - Add keyboard bindings for A/D and/or the Left/Right arrow keys.
- Create a
Jumpaction with type Button. - Bind Jump to Space.
- Save the asset.
Add a PlayerInput component to the Player and assign the Input Actions asset. If you use the callback approach below, set the component’s behavior to the callback mode expected by your Unity version, commonly Send Messages. The callback method names must match the action names: OnMove and OnJump.
Two timing rules matter:
Updatefollows rendered frames and is a good place to read short-lived input events.FixedUpdatefollows the physics timestep and is the appropriate place to change physics movement.
Reading only in FixedUpdate can miss a short button press. Applying physics movement only in Update can produce inconsistent results as rendering and physics run at different rates. The script below stores input in fields, reads callbacks as they arrive, and changes Rigidbody2D velocity in FixedUpdate.
Write the first movement script
Create Assets/Scripts/Player/PlayerController.cs and attach it to the Player:
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
[SerializeField] private float moveSpeed = 6f;
[SerializeField] private float jumpSpeed = 12f;
[SerializeField] private Transform groundCheck;
[SerializeField] private float groundCheckRadius = 0.15f;
[SerializeField] private LayerMask groundLayer;
private Rigidbody2D body;
private Vector2 moveInput;
private bool jumpRequested;
private void Awake()
{
body = GetComponent<Rigidbody2D>();
}
public void OnMove(InputAction.CallbackContext context)
{
moveInput = context.ReadValue<Vector2>();
}
public void OnJump(InputAction.CallbackContext context)
{
if (context.performed)
jumpRequested = true;
}
private void FixedUpdate()
{
body.linearVelocity = new Vector2(
moveInput.x * moveSpeed,
body.linearVelocity.y
);
if (jumpRequested && IsGrounded())
{
body.linearVelocity = new Vector2(
body.linearVelocity.x,
jumpSpeed
);
}
jumpRequested = false;
}
private bool IsGrounded()
{
return Physics2D.OverlapCircle(
groundCheck.position,
groundCheckRadius,
groundLayer
);
}
private void OnDrawGizmosSelected()
{
if (groundCheck == null)
return;
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(
groundCheck.position,
groundCheckRadius
);
}
}
This example uses Rigidbody2D.linearVelocity, the relevant property name for the Unity 6.1 API targeted here. Older tutorials commonly use Rigidbody2D.velocity. Do not silently mix code from different Unity versions; if your editor reports that linearVelocity is unavailable, check the exact editor and API documentation rather than guessing.
Directly controlling horizontal velocity makes the first prototype easy to tune while gravity controls the vertical component. It is not automatically the best movement model for every platformer. A polished precision controller may eventually use acceleration, custom collision handling, coyote time, jump buffering, and slope rules.
Add reliable ground detection
- Right-click the Player in the Hierarchy and choose Create Empty Child.
- Name the child
GroundCheck. - Move it just below the player’s feet.
- Drag it into the script’s Ground Check field.
- Set the player’s Ground Layer field to the Ground layer.
- Set the radius to a small value such as
0.15.
The overlap circle must be large enough to detect the floor but small enough not to detect nearby walls or platforms. A check placed inside the player collider, or a layer mask set to Nothing, can make the result confusing. The yellow gizmo appears when the Player is selected, letting you inspect the check area in the Scene view.
This grounded check prevents infinite midair jumping. It also makes the architecture visible: the player has a defined sensor, a defined ground layer, and a condition that must be true before jumping.
Rank #4
Use Tilemaps when the level grows
Once the individual-platform prototype works, create a scalable level workflow:
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitches- Create a Grid.
- Add a Tilemap beneath it.
- Open the Tile Palette.
- Prepare tile assets from your environment artwork.
- Paint the platforms.
- Add a
TilemapCollider2D. - Assign the Tilemap to the Ground layer.
A CompositeCollider2D can be useful where appropriate to combine collider geometry, but it is not required for the first test. Tilemaps introduce additional concepts—Grid, Tile Palette, tile assets, collider generation, and sorting—so they are better learned after the player can already run and jump. Unity describes Tilemap in its 2D game-creation workflow.
One-way platforms and slopes should wait. One-way platforms involve Platform Effector 2D, dropping through behavior, and edge cases involving collider thickness and downward speed. Slopes require surface normals, slope limits, and special handling to prevent sliding or false airborne states.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Add a simple camera
Select the Main Camera and set its projection to Orthographic. Keep its Z position behind the 2D scene. For a very small prototype, parenting the camera to the player works, but it also copies every vertical movement and makes later room transitions awkward.
A small follow script provides more control. Create Assets/Scripts/World/CameraFollow.cs:
Free tools Windows power users keep installed
One-click scans. No signup required.
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
[SerializeField] private Transform target;
[SerializeField] private float smoothTime = 0.1f;
private Vector3 velocity;
private void LateUpdate()
{
if (target == null)
return;
Vector3 targetPosition = new Vector3(
target.position.x,
target.position.y,
transform.position.z
);
transform.position = Vector3.SmoothDamp(
transform.position,
targetPosition,
ref velocity,
smoothTime
);
}
}
Attach it to the camera and drag the Player into its Target field. LateUpdate lets the camera follow after the player’s movement for the frame has been processed.
Best Value
A production platformer usually needs camera bounds, look-ahead, dead zones, room transitions, and limits that prevent the camera from showing outside the level. Those are later improvements, not requirements for this milestone.
Add animation only after movement works
Use the placeholder until the physics and input loop is reliable. Then:
- Import a sprite sheet.
- Create animation clips for Idle, Run, Jump, and Fall.
- Create an Animator state machine.
- Drive transitions with horizontal speed, vertical speed, and grounded state.
- Flip the SpriteRenderer horizontally when changing direction instead of making separate left/right clips where appropriate.
Unity’s current manual documents animation clips and Animator state machines. Animation should display the movement system, not hide a movement system that has not been debugged.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchTest the milestone
Press Play and verify each result separately:
- Press left and right. The player moves horizontally.
- Release the keys. Horizontal movement stops according to the controller’s direct-velocity model.
- Gravity pulls the player down.
- The player lands on the floor and platforms.
- Jump works while grounded.
- Jump does not work repeatedly in midair.
- The player does not rotate.
- The camera keeps the player visible.
- The Console contains no repeated errors.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Player falls through the floor | Missing collider, disabled collider, trigger floor, or collision-layer problem | Confirm both Collider2D components exist, the floor is not Is Trigger, and the layer collision matrix permits contact. |
| No movement | Input asset or callback is not connected | Check the PlayerInput asset, active action map, behavior mode, binding path, and that the script is attached. Add temporary logging to OnMove. |
| Jump never works | Ground check or mask is wrong | Select the Player, inspect the yellow gizmo, move GroundCheck slightly below the feet, and confirm Ground is included in groundLayer. |
| Infinite jumping | Jump is applied without a grounded condition | Keep the overlap test in the jump branch and verify it is checking only the Ground layer. |
| Player tips over | Z rotation is not constrained | Freeze Z rotation on Rigidbody2D and inspect uneven collision geometry. |
| Player jitters | Transform and Rigidbody2D are both being moved, or scripts compete | Use one movement system, apply physics changes in FixedUpdate, and review Rigidbody2D interpolation and collision settings. |
Physics choices to understand early
Rigidbody2D versus a custom controller
Rigidbody2D is the right starting point here because it gives a beginner gravity, collision, and a playable result quickly. Its trade-off is that default physics can feel slippery and may require careful treatment of slopes, walls, and moving platforms.
A custom kinematic controller can provide more deterministic acceleration, jump height, coyote time, and collision response, but it requires more code and introduces more edge cases. It is often appropriate for a precision platformer, not necessarily for the first lesson.
Velocity versus forces
Direct velocity is straightforward to tune. Forces are more physically expressive, but repeatedly applying force without a speed cap can create runaway acceleration and floaty controls. Platformers generally prioritize intentional controls over physical realism.
Rigidbody2D settings
- Body Type: Dynamic is the usual choice for this physics-based player.
- Gravity Scale: controls how strongly gravity affects the player.
- Constraints: freeze Z rotation.
- Collision Detection: continuous detection may help fast-moving objects, but it is not a universal fix.
- Interpolate: can smooth visual motion when appropriate.
- Mass and drag: leave near defaults until the basic controller is working.
What belongs in the next part
After this prototype is stable, build outward in this order:
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →- Better movement feel, including acceleration and deceleration
- Coyote time and jump buffering
- Sprite sheets and Animator parameters
- Tilemap-based levels
- One-way platforms and slopes
- Hazards, enemies, and damage
- Checkpoints and respawning
- Audio, UI, menus, and scene transitions
- Build settings and deployment
The Unity Learn Player character and movement course is a useful structured follow-up for readers who want more guided practice with 2D control and the Input System.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




