I would..
A) create a scene for an Obstacle with a script with a func setHole(left :int, width :int, angle :float)
B) prepare few obstacles during first game loading (based on your sketch, you'll need ~8 of them?).
C) recycle obstacles going out of screen, set new hole via setHole
, place them above the top of the game scene and make them move to bot again
--
If your obstacles are going to be made out of textures (fancy animations, pixel perfect graphics or so) you may create multiple types of obstacle scene and recycle few types.
If your holes are not going to be quads only, you also may want to prepare some types with different func setHole
eg. setHoles(holes :Array)
for multiple holes and so on.
I do not believe (based on your sketch) there are some heavy calculations needed for obstacle placing during runtime. May you elaborate on this point? What calculations are you perfrorming currently in solution 1?
In case you are going to have so many different types of obstacles (with saws, lasers, goos, spikes, two holes etc.) you may prepare that many obstacle scenes, precache (save to array) them per type and duplicate them via .duplicate()
during loading. This way you'll go your heavy calculations once per obstacle only (I suppose that calculations are needed only for left and right sides of obstacles).