Wie du schon richtig festgestellt hast: du solltest auf irgendeine Art speichern, an welcher Stelle du bereits welches Terrain generiert hast. Dann musst du auch kein komisches Zeug mehr mit Physik und Kollisionen machen, um zu erraten, ob schon Terrain vorhanden ist.
Ist das Vorhanden, musst du dich auch nicht mehr darauf beschränken, nur bei Bewegungen zu prüfen, ob Terrain generiert werden muss. Für den anfang wäre es einfacher, diese Prüfung immer durchzuführen. Macht man es richtig, dann wird auch nur so viel Terrain wie nötig erzeugt.
Bedenke, dass du mit den Fließkommazahlen (Vector2) aufpassen musst. Ganze Zahlen lassen sich, sofern sie nicht zu groß sind, problemlos darstellen, aber manche Zahlen mit Nachkommastellen (bspw. 0,1) können nicht mit binären Fließkommazahlen (endlicher Länge) dargestellt werden.
Du könntest an den einen oder anderen Stellen den Code besser lesbar gestalten, indem du über Erweiterungsmethoden die vorhandenen Strukturen um Methoden erweiterst, statt die entsprechenden Berechnungen selbst unter den Code zu mischen. Ein Beispiel wäre dabei eine Rundungsmethode für Fließkommazahlen, sowie eine Überladung, die auf eine bestimmte Anzahl von Nachkommastellen rundet (bspw. -1 Nachkommastellen -> Runden auf Zehner).
Weiterhin solltest du nicht einfach einen festen Wert (50) wählen, sondern dies anhand der Kamera ermitteln. Du kennst den FOV-Wert, Abstand der Kamera zum Terrain und größtmögliche Tiefpunkte des Terrains bzw. du kennst den orthographicSize, womit du die notwengide Höhe bekommst, und anhand des Seitenverhältisses kann der richtige Wert für die Breite ermittelt zu werden. Solltest du später einen Zoom einfügen, wäre das bereits berücksichtigt (da das immer über die Manipulation einer der Werte durchgeführt wird).