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 with random positioning

Discussion in '2D' started by Nitro00, Feb 5, 2018.

  1. Nitro00

    Nitro00

    Joined:
    Jan 11, 2018
    Posts:
    18
    So, I am making a 2D game where the camera slowly climbs up and the player has to keep up with the camera's movements by following the platforms created as the camera is moving upwards. Now, I have managed to instantiate the prefab I have at a position above the last position but I am having the following problems:

    1. The objects aren't placed random enough
    2. The for loop does not then go through the newly created object's y coordinate
    3. It instantiates the floor rapidly as long as the floor is above the empty game object I am using as a reference point.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Distance_Checker : MonoBehaviour {
    6.  
    7.     GameObject [] floors;
    8.     public GameObject floor;
    9.     Quaternion quat = Quaternion.Euler(0f, 0f, 0f);
    10.  
    11.     // Use this for initialization
    12.     void Start () {
    13.         floors = GameObject.FindGameObjectsWithTag("Objects");                                                // finds the floors
    14.  
    15.     }
    16.  
    17.     // Update is called once per frame
    18.     void Update () {
    19.        
    20.         for(int i = 0; i < floors.Length; i++){
    21.            
    22.             if (floors [i].transform.position.y > transform.position.y) {
    23.                
    24.  
    25.                 if (GetComponentInParent<Camera_Raise> ().moved == true) {                                                                    // A bool to determine when the camera starts moving upwards
    26.                    
    27.                     Vector2 pos = new Vector2 (randomX (floors [i].transform.position.x), randomY (floors [i].transform.position.y));        // finds out the position for the new floor
    28.  
    29.                     Instantiate (floor, pos, quat);                                                                            // instantiates floors
    30.                 }
    31.  
    32.             } else {
    33.                 floors [i].tag = "Lower";                                                                                        // optimization purposes
    34.             }
    35.  
    36.  
    37.         }
    38.  
    39.     }
    40.  
    41.     float randomX(float objectX){                                                                    // random generation for X coordiante
    42.  
    43.         float x = objectX + Random.Range (-6, 6);
    44.  
    45.         return x;
    46.     }
    47.  
    48.     float randomY(float objectY){                                                                    // random generation for Y coordiante
    49.  
    50.         float y = objectY + Random.Range (1, 2);
    51.  
    52.         return y;
    53.     }
    54.  
    55.  
    56. }
    57.  
    Any ideas?
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I'd like to help.

    For starters, I would recommend that you try some beginner tutorials, if you have not already.
    It's not fun to get stuck or get in too deep without a solid foundation.
    If you've already done that, that's good. :)

    Perhaps you want to ensure that the camera has moved far enough before you spawn new platforms? Then, also maybe limit how many are newly spawned for each camera "move".

    As for why the loop doesn't take new objects into account, it's because the array is never added to.
    I would suggest that you consider using an object pool, where you recycle the platforms. It's good practice, useful, and can be a positive learning experience, if you aren't familiar with it.
    For your situation, you could use a List instead of an array, get the original game objects in the scene by dragging them into the list, and when you instantiate new ones, add them to the list.

    With an object pool, you would recycle them, instead of creating new ones. Once it's "x amount" below you (or otherwise out of the way), then you put it back into the pool for later use. You only create new ones when needed beyond that current storage of the pool's size*.

    The random.range for integers is lower inclusive and upper exclusive. When you ask for a random integer between 1 and 2, the only possible value is '1'.

    This may not be the best answer, but I was a bit confused by your post. I hope some stuff here is helpful for you going forward. :)
     
    Nitro00 likes this.
  3. Nitro00

    Nitro00

    Joined:
    Jan 11, 2018
    Posts:
    18
    Yes I have gone through some of the beginner tutorials like Roll a Ball!

    I had gone through and modified some of it to work better. I've added a check so that it can only produce 100 platforms. I tried making the floors get added to the array by declaring it in update but it only accounts for 1 new floor meaning only 2 floors are created. Your list idea seems like it would work perfectly for my case so I'll go ahead and try that!!
     
  4. Nitro00

    Nitro00

    Joined:
    Jan 11, 2018
    Posts:
    18
    Just managed to integrate the list and it works like a charm! I see what you said about the Random.random part and I can see that it works with a few things I would need to work out. However, I have noticed one issue. I believe it is generating 2 of them at a time, and as a result, everything is in blocks of 2. I can edit in the code if you want. Thanks for the help with the lists though, major improvement!
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I'm glad I could help some.

    I did read your previous message, too, but waited to see your next update. It would have been possible to use an array, too (I only mention this, in case you didn't know), but a list is "easier", in that it basically handles what you'd want with an array (resizing) in its code.

    Please do post some updated code, so I can see if I spot what you're talking about.
     
  6. Nitro00

    Nitro00

    Joined:
    Jan 11, 2018
    Posts:
    18
    Here is the updated code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Floor_Generate : MonoBehaviour {
    6.  
    7.     public GameObject floor;
    8.     Quaternion quat = Quaternion.Euler(0f, 0f, 0f);
    9.     int runs = 0;
    10.     public int max = 1000;
    11.  
    12.  
    13.     List <Floor_ListSet> floors = new List<Floor_ListSet>();
    14.     GameObject[] floorsAtStart;
    15.  
    16.  
    17.     // Use this for initialization
    18.     void Start () {
    19.  
    20.         floorsAtStart = GameObject.FindGameObjectsWithTag("Objects");
    21.  
    22.         for (int i = 0; i < floorsAtStart.Length; i++) {
    23.  
    24.             floors.Add (new Floor_ListSet (floorsAtStart [i]));
    25.  
    26.         }
    27.  
    28.  
    29.  
    30.     }
    31.    
    32.     // Update is called once per frame
    33.     void Update () {
    34.  
    35.         for (int i = 0; i < floors.Count; i++) {
    36.  
    37.             if (floors [i].X > transform.position.x && runs < max) {
    38.  
    39.                 int RandomX = Random.Range (10, 20);
    40.                 int RandomY = Random.Range (-2, 2);
    41.  
    42.                 floors.Add(new Floor_ListSet(Instantiate (floor, new Vector2 (floors [i].X + RandomX, RandomY), quat)));
    43.  
    44.  
    45.  
    46.                 runs++;
    47.  
    48.             }
    49.  
    50.  
    51.         }
    52.  
    53.  
    54.     }
    55.  
    56.  
    57.  
    58. }
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I am a little rusty on this thread, but are you saying the code in the update loop is creating 2 at a time?
    I'm a little bit confused by your code. You'll be rechecking the same floors over n over, again.

    Your list will also just be growing n growing, potentially.

    I really think you should consider a pool of objects, and when one goes out of range, reposition it to a new valid spot.
     
  8. Nitro00

    Nitro00

    Joined:
    Jan 11, 2018
    Posts:
    18
    It is really only meant to generate the level once and then it's pretty much never run again. But I see a pattern where it generates the floors in blocks of 2.
     
  9. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Yes, it was my mistake to say it would keep growing always.

    I'm not sure how it comes in pairs, unless you have 2 of these scripts. I mean literally at the same moment, it can only make 1. However, you do go over the same parts of the list, again and again -- is that intentional?

    Would you maybe want to go over only the portion of the list that's new if you're building the level in 1 shot? Otherwise, unless I'm mistaken again, the pieces would be re-using the same smaller indexes in the list as their values, before the random offset.
     
  10. Nitro00

    Nitro00

    Joined:
    Jan 11, 2018
    Posts:
    18
    I feel like it has more to do with the random numbers as they are surely not random entirely. The script would be better optimized if I only went through the newly generated floors, however, the reason for that is currently so I can add random item generation at a certain position on those floors in different intervals.