(Two ideas here. See bottom for the "simpler" one.)
Answering exact question:
(Instantiate each time the player reaches right/left edge)
Assuming your stages are of similar complexity to those in the video you linked, you can simply give unique GameObject tags to each of the dynamic (can be destroyed/deleted) children in the prefab.
Then have a global StageManager object/script used to keep track of changes, perhaps a dictionary mapping from tag to state.
With that in place, next have the code that instantiates the stage prefab recurse down the object's tree. Get each child object's tag and ask the StageManager about the state of that tag. Register, ignore, or kill the child object depending on the StageManager's response.
Maybe try something like so (warning: have not compiled or tested this):
public void instantiateStagePrefab(GameObject stageObjPrefab)
{
GameObject stageObj = GameObject.Instantiate(stageObjPrefab) as GameObject;
for( int i=0; i<stageObj.transform.childCount; i++ )
{
registerOrKill( stageObj.transform.GetChild(i) );
}
}
private void registerOrKill(GameObject childObject)
{
StageManager.instance.ensureRegistered(childObject.tag);
if( !StageManager.instance.getState(childObject.tag) )
{
GameObject.Destroy(childObject);
}
else
{
for( int i=0; i<childObject.transform.childCount; i++ )
{
registerOrKill( childObject.transform.GetChild(i) );
}
}
}
Then in StageManager, have:
... (Singleton stuff) ...
private Dictionary<string,bool> tagStates = new Dictionary<string,bool>();
...
public void ensureRegistered(GameObject tagObj)
{
if(! tagStates.ContainsKey(tagObj.tag))
{
tagStates[tagObj.tag] = true;
}
}
public bool getState( string tag )
{
bool state = true;
if( tagStates.TryGetValue(tag, out state) )
{
return state;
}
return true; // if it's uninitialized, it's active by default.
}
public bool setState( string tag, bool newState )
{
tagStates[tag] = newState; // overwrite old value or add as new entry
}
Finally, have your "collected coin!" code:
- Call setState with the coin's tag and newState=false.
- Use GameObject.FindGameObjectsWithTag(tag) to locate all of the already-instantiated objects with that tag. Then GameObject.Destroy() those.
With this bookkeeping code, any new instantiations of the prefab should be free of any objects you've already deemed 'dead'. This applies to enemies, collectibles, platforms, etc. Really, anything you want to give a tag (again: critical that the tags are unique!).
Simpler answer in the same spirit:
I think it's possible to just instantiate the prefab 2 or 3 times, side-by-side. Then just move the player and camera "back" a screen when the player nears the edge.
In order for this to look smooth, you'll need to make sure all the animated objects are animated identically (same position, same frame, etc.) or there will be visual artifacts when you shift the player and camera.
You'll still benefit from the 'tag' approach here. E.g. when a coin is collected, the other 1-2 coins with tag "Coin26" can be found by tag and deleted.
This approach takes a lot less bookkeeping, but will also be a lot nicer on whatever machine you're running this on. Instantiating a large "stage" prefab regularly might cause hiccups in rendering/responsiveness, no fun.
No code suggestions here - just move the camera and player left or right by the width of the stage prefab. Should be imperceptible.
Hope all this helps!