I’m working on an infinite scroller where the player and the camera are static while the platform and the background move towards them. Once an object enters the camera for the first time, it creates a copy of itself at the right edge of the BoxCollider2D, and once it exists it, it gets destroyed.
Each of the Floor, Ceiling, Sky, Clouds and Foreground have the following script attached to them:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InfiniteScroller : MonoBehaviour
{
// Variables to control the parallax effect
// A value of 1 means the object will move at the same speed as the camera
// A value of 0 means the object will not move at all
public float parallaxCoefficient = 1;
// Variable to store the player controller script where the speed is stored
PlayerController playerController;
// Collider and its properties
BoxCollider2D col;
float colPositionX;
float colHalfWidth;
// Camera and its properties
Camera cam;
float camPositionX;
float camHalfWidth;
// Variables to control the state of the object
bool hasCreatedNewObject;
bool visibleFirstTime;
// Start is called before the first frame update
void Start()
{
// Fetch the collider and its properties
col = GetComponent<BoxCollider2D>();
colPositionX = col.transform.position.x;
colHalfWidth = col.size.x/2;
// Fetch the camera and its properties
cam = Camera.main;
camPositionX = cam.transform.position.x;
camHalfWidth = cam.aspect * cam.orthographicSize;
// fetch the player controller, we do it in start() because fetching the player controller in update() in every frame is expensive
playerController = GameObject.Find("Player").GetComponent<PlayerController>();
// set the state of the object to its initial state
hasCreatedNewObject = false;
visibleFirstTime = CheckIsVisible();
}
// Update is called once per frame
void Update()
{
// determine whether the object is visible
bool visible = CheckIsVisible();
// if the object is visible for the first time, create a new object
if (visible)
{
if (!hasCreatedNewObject) {
// create a new object
GameObject newObject = Instantiate(gameObject, new Vector2(colPositionX + colHalfWidth, transform.position.y), Quaternion.identity);
// set the state of the object to its initial state
hasCreatedNewObject = true;
}
if (!visibleFirstTime) visibleFirstTime = true;
}
else
{
// if the object is not visible, destroy it
if (visibleFirstTime) Destroy(gameObject);
}
}
// FixedUpdate is called once per physics update
void FixedUpdate()
{
// get the speed from the player controller
float speed = playerController.speed;
// // Move the object to the left
transform.Translate(Vector2.left * speed * parallaxCoefficient * Time.deltaTime);
}
// check if the object is visible by the camera
bool CheckIsVisible()
{
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(cam);
return GeometryUtility.TestPlanesAABB(planes, col.bounds);
}
}
The result is not really what i had in mind, since the spawned objects get inside each other. Here’s the result (you can see the collider boxes overlap):
Here’s how my project hierarchy looks like: