Skip to content

Instantly share code, notes, and snippets.

@arunoda
Created September 30, 2020 09:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arunoda/51a9d738b18bac2a43b3870488edc204 to your computer and use it in GitHub Desktop.
Save arunoda/51a9d738b18bac2a43b3870488edc204 to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InfiniteMovingBelt : MonoBehaviour
{
public GameObject item;
public float speed = -1f;
public float spawnOffsetFromScreen = 1f;
public float destroyOffsetFromScreen = 1f;
public float spawnDistance = 5f;
public float spawnProbability = 1f;
private readonly List<GameObject> instances = new List<GameObject>();
void Start()
{
// Create the instance
MakeInitialSpawning();
}
void Update()
{
foreach(GameObject instance in instances.ToArray())
{
if (CanDestroy(instance))
{
Destroy(instance);
instances.Remove(instance);
continue;
}
Vector3 originalPos = instance.transform.position;
float posX = originalPos.x + (speed * Time.deltaTime);
Vector3 newPosition = new Vector3(posX, originalPos.y, originalPos.z);
instance.transform.position = newPosition;
}
SpawnIfNeeded();
}
private Vector3 GetScreenSize()
{
var screenSizePixels = new Vector3(Screen.width, Screen.height, 0);
return Camera.main.ScreenToWorldPoint(screenSizePixels);
}
private bool CanDestroy(GameObject i)
{
Vector3 screenSize = GetScreenSize();
return i.transform.position.x < GetDestroyX();
}
private void SpawnIfNeeded()
{
GameObject last = instances[instances.Count - 1];
float diff = GetSpawnX() - last.transform.position.x;
if (diff >= spawnDistance)
{
SpawnWithProbability(GetDefaultStartPos());
}
}
private float GetSpawnX()
{
return GetScreenSize().x + spawnOffsetFromScreen;
}
private float GetDestroyX()
{
return -(GetScreenSize().x + destroyOffsetFromScreen);
}
private GameObject SpawnWithProbability(Vector3 startPos)
{
bool canSpawn = Random.Range(0f, 1f) < spawnProbability;
if (canSpawn)
{
return SpawnItem(startPos);
}
return SpawnItemAndHide(startPos);
}
private GameObject SpawnItem(Vector3 startPos, bool addToFront = false)
{
GameObject instance = Instantiate<GameObject>(item, startPos, Quaternion.identity);
if (addToFront)
{
instances.Insert(0, instance);
} else
{
instances.Add(instance);
}
return instance;
}
private GameObject SpawnItemAndHide(Vector3 startPos)
{
startPos.y = 10;
GameObject instance = Instantiate<GameObject>(item, startPos, Quaternion.identity);
instances.Add(instance);
return instance;
}
private Vector3 GetDefaultStartPos()
{
return new Vector3(
GetSpawnX(),
gameObject.transform.position.y,
gameObject.transform.position.z
);
}
private void MakeInitialSpawning()
{
Vector3 startPos = GetDefaultStartPos();
while(startPos.x > GetDestroyX())
{
SpawnItem(startPos, addToFront:true);
startPos.x -= spawnDistance;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment