Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

[HELP] Endless world generator

Discussion in '2D' started by FirefIy, Jul 17, 2015.

  1. FirefIy

    FirefIy

    Joined:
    Apr 15, 2015
    Posts:
    23
    Hello,

    I'm a begginer programmer and I've wrote up a script that would create an endless world for me, however I can't get it working properly. Right now what my script does is and how generator works is:

    1. I have an invisible generator object that has a Moving script attached to it. (Just moves to the left, and gets removed when reaches a certain point)

    2. This object creates a set of tiles (objects) with a specific width. There are 3 sprites used. Each being different, the 2nd sprite is used for extending the overall platform.

    3. These objects also have a moving script attached to them, but since they're moving at a same speed they look as if they are one object, in reality it could be 40 different objects with proper spacing (width).

    4. As soon as player reaches the trigger (BoxCollider 2D Trigger) of the last object a NEW invisible generator object is being created but for some reason it overlaps the already made 40 blocks I have and then it does NOT create any new ones.

    PS.
    I've noticed that Start(); method is only being called ONCE!


    The code:
    Invisible Generator Object
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class WorldGenerator : MonoBehaviour {
    6.  
    7.  
    8.     public Vector2 speed = new Vector2 (2, 2);
    9.     public bool movingLeft = true;
    10.  
    11.     private Vector2 direction;
    12.     private bool toCreate = false;
    13.     private CameraFollow camera;
    14.     public short minTiles = 1;
    15.     public short maxTiles = 5;
    16.     private bool newTile = false;
    17.  
    18.     //GameObject player;
    19.     Player player;
    20.  
    21.     public Transform worldGenerator;
    22.  
    23.     public bool Repeating = false;
    24.     public float tileWidth;
    25.  
    26.     private float Lenght = 0;
    27.  
    28.  
    29.     public static short layerCounter = 1;
    30.  
    31.     public Transform[] layer_1 = new Transform[layerCounter];
    32.  
    33.     public Transform[] layer_2 = new Transform[layerCounter];
    34.  
    35.     public Transform[] layer_3 = new Transform[layerCounter];
    36.  
    37.     // Use this for initialization
    38.     void Start () {
    39.         camera = GameObject.FindGameObjectWithTag ("MainCamera").GetComponent<CameraFollow> ();
    40.         //    player = GameObject.FindGameObjectWithTag ("Player");
    41.         player = GameObject.FindGameObjectWithTag ("Player").GetComponent<Player> ();
    42.         Debug.Log ("I was made!");
    43.     }
    44.  
    45.     void Update()
    46.     {
    47.         float randomSpace = Random.Range(2,20);
    48.         if(movingLeft)
    49.             direction = new Vector2(-1, 0);
    50.         else
    51.             direction = new Vector2(1, 0);
    52.      
    53.         // Movement
    54.         Vector3 movement = new Vector3(
    55.             speed.x * direction.x,
    56.             speed.y * direction.y,
    57.             0);
    58.      
    59.         movement *= Time.deltaTime;
    60.         transform.Translate(movement);
    61.  
    62.         Debug.Log ("Generated tile has a lenght of " + Lenght);
    63.      
    64.      
    65.         if (Repeating) {
    66.             float amount = Random.Range((int)minTiles,(int)maxTiles);
    67.             if(player.tileReached){
    68.                 Debug.Log ("Removing generator and adding new one.");
    69.                 Destroy(gameObject);
    70.              
    71.                 toCreate = false;
    72.                 player.tileReached = false;
    73.              
    74.                 var nextTiles = Instantiate(worldGenerator) as Transform;
    75.                 nextTiles.position = new Vector3(player.transform.position.x + Lenght + 280F, transform.position.y, transform.position.z);
    76.              
    77.             }
    78.          
    79.             if((transform.position.x <= Camera.main.transform.position.x+2F) && toCreate == false){
    80.              
    81.                 if(layer_1 == null)
    82.                     return;
    83.              
    84.                 int Counter = (int) (amount + layer_1.Length) - 1;
    85.                 Lenght = (float) Counter * tileWidth;
    86.              
    87.  
    88.                 if(layer_1.Length > 0){
    89.                     int x = 1;
    90.                     while(Counter > 0){
    91.                      
    92.                      
    93.  
    94.                      
    95.                         if(Counter == ((int) (amount + layer_1.Length) - 1)){
    96.                             var firstObject = Instantiate(layer_1[0]) as Transform;
    97.                             firstObject.position = new Vector3(transform.position.x+(float) tileWidth, transform.position.y, transform.position.z);
    98.                      
    99.                         }
    100.                      
    101.                         else if(Counter == 1){
    102.                             var lastObject = Instantiate(layer_1[2]) as Transform;
    103.                      
    104.                             lastObject.position = new Vector3(transform.position.x+(float) tileWidth * (float) (amount-1 + layer_1.Length),
    105.                                                              transform.position.y, transform.position.z);
    106.                          
    107.                             toCreate = true;
    108.                          
    109.                         } else {
    110.                             var objectTransform = Instantiate(layer_1[1]) as Transform;
    111.                             objectTransform.position = new Vector3(transform.position.x + (float) (tileWidth * x) ,
    112.                                                                   transform.position.y, transform.position.z);
    113.  
    114.                         }
    115.                      
    116.                         x++;
    117.                         Counter--;
    118.                     }
    119.                  
    120.                  
    121.                  
    122.                  
    123.                 }
    124.                
    125.             }
    126.  
    127.         }
    128.      
    129.     }
    130.  
    131.  
    132. }
    133.  

    Last object's collider checking script
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class TileChecker : MonoBehaviour {
    6.     Player player;
    7.     // Use this for initialization
    8.     void Start () {
    9.         player = GameObject.FindGameObjectWithTag ("Player").GetComponent<Player> ();
    10.     }
    11.  
    12.     // Update is called once per frame
    13.     void Update () {
    14.  
    15.     }
    16.  
    17.     void OnTriggerEnter2D(Collider2D col){
    18.         if(col.CompareTag("Player")){
    19.             player.tileReached = true;
    20.         }
    21.     }
    22.     void OnTriggerStay2D(Collider2D col){
    23.         if(col.CompareTag("Player")){
    24.             player.tileReached = true;
    25.         }
    26.     }
    27.  
    28.     void OnTriggerExit2D(Collider2D col){
    29.         if(col.CompareTag("Player")){
    30.             player.tileReached = false;
    31.         }
    32.     }
    33.  
    34. }
    35.  
    How it looks like at first



    Collider of the last object.



    (Start(); is ONLY BEING CALLED ONCE)

    PS.
    I'm really sorry for my horrible code writing, I'm still studying.
     

    Attached Files:

  2. FirefIy

    FirefIy

    Joined:
    Apr 15, 2015
    Posts:
    23
    Anyone?
     
  3. Zk

    Zk

    Joined:
    May 25, 2013
    Posts:
    19
    I just did some testing, and it does look like Start() won't be called on the instantiated object. If you use Awake() instead of Start() it should be called on the instantiated object as well.
     
  4. tedthebug

    tedthebug

    Joined:
    May 6, 2015
    Posts:
    2,570
    I was taught that If the script is on the prefabbed object then it is called as soon as each prefab is instantiated. I.e start is only ever called once so If the script is on an object that is constant in the game then it is only called the once.
     
  5. FirefIy

    FirefIy

    Joined:
    Apr 15, 2015
    Posts:
    23
    Alright, anyway I found a workaround. I decided that there's no need for a different object. Instead what I'm doing is checking if player has reached the last tile, or is close to it. And if (true) then it spawns next set of tiles, and keeps doing it endlessly, i.o. Endless world with endless amount of platforms.
     
  6. tedthebug

    tedthebug

    Joined:
    May 6, 2015
    Posts:
    2,570
    You can create the illusion of an endless world if the ground etc is always the same by having a large plane with the image set on it & tiled & use an offset scroll script to make the image on the plane scroll. That way it looks like the character is moving even though it is stationary. If the scroll is linked to the player controls when the person uses keys etc to move the character they actually move the image on the plane