Parallax scrolling:
An effect that you find in every single 2D game for 15 years is “parallax scrolling“.
To make it short, the idea is to move the background layers at different speeds (i.e., the farther the layer is, the slower it moves). If done correctly, this gives an illusion of depth. It’s a cool, nice and easy-to-do effect.
Idea ???
Adding a scrolling axis need a bit of thinking on how we will make the game with this new aspect.
What do we want to move?
Parallax Scrolling
We have a decision to take here :
First choice: The player and the camera move. The rest is fixed.
Second choice: The player and the camera are static. The level is a treadmill.
The first choice is a no-brainier if you have a Perspective camera. The parallax is obvious: background elements have a higher depth. Thus, they are behind and seems to move slower.
But in a standard 2D game in Unity, we use an Orthographic camera. We don’t have depth at render.
About the camera:
Remember the “Projection” property of your camera game object. Perspective means that the camera is a classic 3D camera, with depth management. Orthographic is a camera that renders everything at the same depth. It’s particularly useful for a GUI or a 2D game.
In order to add the parallax scrolling effect to our game, the solution is to mix both choices. We will have two scrolling:
The player is moving forward along with the camera.
Background elements are moving at different speeds (in addition to the camera movement).
Parallax Scrolling
Here is the script for Scrolling background:
//------ Script is created by --------// //---------------- OZ ----------------// //------ http://ozappstudio.com/ -----------------// //------ http://ift.tt/1ok9fLP --------//
using UnityEngine; using System.Linq; using System.Collections.Generic;
public class InfiniteScrolling : MonoBehaviour { public float speed; private List backgroundPart;
void Start() { backgroundPart = new List(); for (int i = 0; i < transform.childCount; i++) { Transform child = transform.GetChild(i); if (child.GetComponent() != null) { backgroundPart.Add(child); } } backgroundPart = backgroundPart.OrderBy ( t => t.position.x ) .ToList(); }
void Update() { transform.Translate (Vector2.right * Time.deltaTime * speed);
Transform firstChild = backgroundPart.FirstOrDefault();
if (firstChild != null) { if (firstChild.position.x < Camera.main.transform.position.x) { if (firstChild.GetComponent().IsVisibleFrom(Camera.main) == false) { Transform lastChild = backgroundPart.LastOrDefault();
Vector3 lastPosition = lastChild.transform.position;
Vector3 lastSize = ( lastChild.GetComponent().bounds.max – lastChild.GetComponent().bounds.min );
firstChild.position = new Vector3(lastPosition.x + lastSize.x, firstChild.position.y, firstChild.position.z);
backgroundPart.Remove(firstChild); backgroundPart.Add( firstChild ); } } } } }
Explanation of Scripting:
We need a public variable to turn on the “looping” mode in the “Inspector” view.
We also have to use a private variable to store the layer children.
In the Start() method, we set the backgroundPart list with the children that have a renderer. Thanks to a bit of LINQ, we order them by their X position and put the leftmost at the first position of the array.
Sprite Renderer Extension:
We Also need some tweaking in our sprite renderer to check if the sprite is visible or not in camera. and also to calculate its bounds dynamically.
Here is our SpriteRendererExtension Script: //------ Script is created by --------// //---------------- OZ ----------------// //------ http://ozappstudio.com/ -----------------// //------ http://ift.tt/1ok9fLP --------//
using UnityEngine;
public static class SpriteRendererExtension { public static bool IsVisibleFrom(this Renderer renderer, Camera camera) { Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera);
return GeometryUtility.TestPlanesAABB(planes, renderer.bounds); } }
Note: We use GeometryUtility for calculating view of our Camera to the sprite.















