Created
September 30, 2020 09:44
-
-
Save arunoda/51a9d738b18bac2a43b3870488edc204 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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