Self Generating 2D Side scroller problem with Prefabs

Hello, I’ve been making this with my friend and we have the main body of the scripts down for the self generating however we have run into a problem we can’t figure out how to solve.

Basically we run a pathCreator script in the main menu that works out which blocks in our 2D side scroller can connect to eachother (a block being a section of the map).

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[System.Serializable]
public class PathCreator : MonoBehaviour {

    private sceneCharateristics currentPrefabI;
    private string currentSceneType;
    private int currentMinEnd;
    private int currentMaxEnd;
    private string currentsceneName;
    private sceneCharateristics compPrefabI;
    private string compSceneType;
    private int compMinStart;
    private int compMaxStart;
    private string compsceneName;
    private List<GameObject> currentCanPath;
    public List<GameObject> levels;
    private sceneCharateristics prefab1Path;
    private List<GameObject> prefab1Canpath;
    private sceneCharateristics prefab2Path;
    private string prefab2Canpath;
    private sceneCharateristics prefabInCanPath;
    private string prefabInCanPathName;
    public List<GameObject> useLevels;


    void Awake() {
        foreach (GameObject go in Resources.LoadAll<GameObject> ("Prefabs")) {
            levels.Add (go);
        }

      
        for (int i = 0; i < levels.Count; i++) {

            currentPrefabI = levels [i].GetComponent<sceneCharateristics> ();
            currentSceneType = currentPrefabI.sceneType;
            currentMinEnd = currentPrefabI.minEnd;
            currentMaxEnd = currentPrefabI.maxEnd;
            currentsceneName = currentPrefabI.name;

            for (int x = 0; x < levels.Count; x++) {

                compPrefabI = levels [x].GetComponent<sceneCharateristics> ();
                compSceneType = compPrefabI.sceneType;
                compMinStart = compPrefabI.minStart;
                compMaxStart = compPrefabI.maxStart;
                compsceneName = compPrefabI.name;

                if (currentsceneName == compsceneName) {
            
                }

                else if (correctType(currentSceneType, compSceneType) && correctMinMax(currentMinEnd, currentMaxEnd, compMinStart, compMaxStart) && notDuplicated(levels [i], levels [x]) ) {

                    currentCanPath = currentPrefabI.canPath;
                    currentCanPath.Add(levels[x]);                
                }
            }
        }

        foreach (GameObject go in Resources.LoadAll<GameObject> ("Prefabs")) {
            useLevels.Add (go);
        }

    }

    public bool correctType( string currentSceneType, string compSceneType) {

        if (currentSceneType == "Landscape" && compSceneType == "Landscape") {
            return true;
        }
    
        else {
            return false;
        }
    }

    public bool correctMinMax( int minEnd, int maxEnd, int minStart, int maxStart) {

        if (minStart == minEnd && maxStart == maxEnd) {
            return true;
        }
        else {
            return false;
        }
    }

    public bool notDuplicated(GameObject prefab1, GameObject prefab2) {
      
        prefab1Path = prefab1.GetComponent<sceneCharateristics> ();
        prefab1Canpath = prefab1Path.canPath;

        prefab2Path = prefab2.GetComponent<sceneCharateristics> ();
        prefab2Canpath = prefab2Path.sceneName;



        for (int i = 0; i < prefab1Canpath.Count; i ++) {
            prefabInCanPath = prefab1Canpath[i].GetComponent<sceneCharateristics> ();
            prefabInCanPathName = prefabInCanPath.sceneName;

            if (prefabInCanPathName == prefab2Canpath) {
                return false;
            }
        }

        return true;
    }
}

and then when you switch scene into the level it generates a level using the characteristics of the prefabs. Using the levelGenerator scripts here:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class levelGenerator : MonoBehaviour {

    public sceneCharateristics currentPrefab;
    public sceneCharateristics prefabAccess;
    public List<GameObject> levelList;
    public List<GameObject> currentPreFabCanPath;
    public List<GameObject> currentPreFabCanPathTemp;
    public List<string> prefabName;
    public List<int> chanceWeight;
    private string prefabNames;
    public int prefabWeights;
    public int Range = 0;
    public int top = 0;
    public int rand;
    public int prefabWidth;
    public int maxNumberOfLevels = 15;

    void Start () {
        levelList.Clear();
        currentPreFabCanPath.Clear ();
        chanceWeight.Clear ();
        prefabName.Clear ();

        GameObject start = Instantiate (Resources.Load ("Prefabs/StartBlock"), new Vector3 (0,0,0), Quaternion.identity) as GameObject;
        levelList.Add (start);

        for (int levelNum = 0; levelNum < maxNumberOfLevels; levelNum++) {

                currentPrefab = levelList [levelNum].GetComponent<sceneCharateristics> ();
              
                currentPreFabCanPath = currentPrefab.canPathdef;
                currentPreFabCanPathTemp = currentPreFabCanPath;
                if (currentPreFabCanPathTemp.Count != 0) {
                    for (int i = 0; i < currentPreFabCanPathTemp.Count; i++) {
                        prefabAccess = currentPreFabCanPathTemp [i].GetComponent<sceneCharateristics> ();
                        prefabWeights = prefabAccess.chanceWeight;
                        prefabNames = prefabAccess.sceneName;
                        prefabWidth = prefabAccess.sceneWidth;

                        prefabName.Add (prefabNames);
                        chanceWeight.Add (prefabWeights);
                    }

                    for (int z = 0; z < chanceWeight.Count; z++) {
                        Range += chanceWeight [z];
                    }

                    rand = Random.Range (0, Range);
                    for (int x = 0; x < chanceWeight.Count; x++) {
                        top += chanceWeight [x];

                        if (rand < top) {
                          

                    

                        
                           
                            GameObject next = Instantiate (currentPreFabCanPath [x], new Vector3 ((levelNum+1)*prefabWidth, 0, 0), Quaternion.identity) as GameObject;
                            
                            levelList.Add (next);
                        

                            top = 0;
                            Range = 0;
                            break;
                        }
                    }
                    currentPreFabCanPathTemp.Clear ();
                    chanceWeight.Clear ();
                    prefabName.Clear ();

                }

            }

       

    }
}

However the problem we have is the pathCreator scripts run, it figures out which sections can link together and then when the levelGenerator script runs it just instantiates the startBlock and nothing else. It will not save what the pathCreator script worked out for us. It is forgetting what we learnt from the pathCreator script.

If we run the game and when we go into the main menu and then scroll through our prefabs and then switch to the next scene, it works as intended. So we are quite confused to what is going on. We have tried going through the scripts and solving it, but we only narrow downed the problem, we still aren’t sure how to fix it.

Thanks in advance for any help! Also we aren’t the best programmers so all help is welcome!

Why have this as two separate scripts? Also, when you load a new scene, the pathCreator and all its info will be lost unless you use, DontDestroyOnLoad.

Hope that’s helpful.

Hi Renman,

I’m that friend being talked about. We use pathCreator to populate a list hat is attached to the prefab (called sceneCharateristics) and doesn’t do anything else other than that. Currently I have it attached to an empty game object.

Am I not able to run this script in the main menu, let it populate the list attached to prefabs then discard it? The pathCreator will never be used again after it has populated the lists.

Will give it a go however :).

Just updating, this worked.

Couple of question revolving around this then:

Considering our pathCreator runs from void Awake() do the script run for a second time on the level swap or due to it having been run on the main menu will it not run again?

If it does run for a second time after loading the level is there a way to stop this?

Thank you for your help though renman!!

If you have object x, with script x, that uses Awake(). Awake is called once at load scene. However, if you use DontDestroyOnLoad() with in that script, if you change scenes, this object will not be destroyed. It will survive the loading of the new scene. As such, all memory will be maintained.