Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Tryflozn · Oct 07, 2013 at 10:57 PM · 2d-platformerlevelgeneratorrandomize

How should I make a C# script for a 2D random platform level generator that goes straight down infinitely?

Hi,

I am really new to C# and to unity so please forgive me if I sound really bad at this, but I wanted to create a C# script in Unity that allows a level manager to grab sections of a level from a pool and randomly place them together upon the character’s Y distance and recycle the level section above the character and place the next sections lower in a random order, when the character travels further down creating an infinite downwards corridor.

How do I do this in C# and keep it optimized for the android to run efficiently?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
4
Best Answer

Answer by VioKyma · Oct 08, 2013 at 12:06 AM

I am keen to help you, but please know that I will not write the script for you, so my answer is not a complete script, but the general structure of one. Please attempt to implement the script, and let me know if you have any questions about writing the script. If you don't know where to start, take a look at the beginner scripting tutorials by Unity. It might be better to start with JavaScript if you have never done any C# coding before. My approach would be:

Firstly, you want to store the pool of level parts/components in an array or list and make it public so you can assign from the editor.

You will probably want to have a Queue to add these level components to so that you have a way of managing the upcoming components.

If there are less than the desired buffer (Queue) size, then add a component. You just need to generate a random number between 0 and the size of the level components size (eg Random.Range(0, componentPool.size);) And just add the component item based on that random number.

Then when you are displaying the level, just create the level one component in advance so the player doesn't have the chance of a blank area for any amount of time.

EDIT: For those viewing this question after the fact, the final script is below.

 public class PlatformManager : MonoBehaviour 
 {
     public int startingNumber;
     public List<string> levelComponents;
     // define it as the height on one or more component objects (The actual value you will need to find out)
     public float componentBuffer;
     public float screenBuffer;
     public List<Transform> platformList;
 
     private Vector3 nextPosition;
     private Transform player;
 
     void Start()
     {
        nextPosition = new Vector3(0.0f, -componentBuffer, 0.0f);
        platformList = new List<Transform>();
        for (int i = 0; i < startingNumber; i++)
        {
           int randComponent = Random.Range(0, levelComponents.Count);
           GameObject newPlatform = PoolManager.Spawn(levelComponents[randComponent]);
           newPlatform.transform.position = nextPosition;
           platformList.Add(newPlatform.transform);
           nextPosition.y -= componentBuffer;
        }
     }
 
     void Update()
     {
        if (player == null)
        {
          player = GameObject.Find("Player(Clone)").transform;
        }
        else
        {
          if (nextPosition.y > player.position.y - screenBuffer)
          {
             int randComponent = Random.Range(0, levelComponents.Count);
             GameObject newPlatform = PoolManager.Spawn(levelComponents[randComponent]);
             newPlatform.transform.position = nextPosition;
             platformList.Add(newPlatform.transform);
             nextPosition.y -= componentBuffer;
          }
 
          if (platformList[0].position.y > player.position.y + screenBuffer)
          {
             PoolManager.Despawn(platformList[0].gameObject);
             platformList.RemoveAt(0);
          }
        }
     }
 }

Comment
Add comment · Show 31 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Tryflozn · Oct 08, 2013 at 08:48 PM 0
Share

Thank you for the reply and I have made progress on trying to script it myself, but of course I'm not clear about everything and maybe even more lost then I think I am.

I would like to show you what I have so far in my scripts.

So I have a manager script that looks like this

 using UnityEngine;
 using System.Collections.Generic;
 
 public class Platform_$$anonymous$$anager : $$anonymous$$onoBehaviour 
 {
 
     public Transform prefab;
     public int numberOfObjects;
     public Vector3 startPosition;
     
     private Vector3 nextPosition;
     private Queue<Transform> objectQueue;
     
 
     void Start () 
     {
         objectQueue = new Queue<Transform>(numberOfObjects);
         for(int i = 0; i < numberOfObjects; i++){
             objectQueue.Enqueue((Transform)Instantiate(prefab));
         }
         nextPosition = startPosition;
         for(int i = 0; i < numberOfObjects; i++)
         {
             Pool$$anonymous$$anager.Spawn("Test_Level_Pool_A");
         }
     }
 
     void Update () 
     {
         if(objectQueue.Peek().localPosition.y < Player.distanceTraveled)
         {
             Pool$$anonymous$$anager.Spawn("Test_Level_Pool_A");
         }
     }
 }

and I’m using these lines to make sure pieces are replaced in the scene when the player travel further downwards. These lines are placed within the player’s control script.

 public static float distanceTraveled;
 
 distanceTraveled = transform.localPosition.y;
 
 

And I also have a pool manager script that is used from this source http://www.booncotter.com/unity-prefactory-a-better-pool-manager/

So in total I have 3 different scripts, now I would like to ask am I on the right track on scripting this level generator?

avatar image VioKyma · Oct 08, 2013 at 10:38 PM 0
Share

Looks like you're well on track to getting it sorted. Is it working as you expect so far?

One thing I will say about what you have though, the Queue object should enqueue each object's transform as it's created, so that you can just pull from the end of the Queue when you have created a new component, then Despawn the parent object of the transform so that you always have the same number (or there about) of components in memory. This will help with memory management for your android target device.

Then all that is left is to randomise your selection of the components to place. If you want it to be truly random, then that is easy, just generate a random number (Random.Range) and use that to reference the component in a component list. If you want some control it is a little more complex, but not difficult.

avatar image Tryflozn · Oct 09, 2013 at 01:27 AM 0
Share

So far I have one section of the level spawn and I can't seem to make the same section spawn again right below it. So when my character makes it to the bottom of the stage he just falls continuously and nothing more seems to happen. I can’t seem to get the level sections to continuously spawn one after another below each other.

One thing I will say about what you have though, the Queue object should enqueue each object's transform as it's created, so that you can just pull from the end of the Queue when you have created a new component, then Despawn the parent object of the transform so that you always have the same number (or there about) of components in memory. This will help with memory management for your android target device.

About what you said, I’m not sure how to approach this. Is there a tutorial that can help me understand this? Or maybe can you create an example of some sort? As I do not fully understand how to do what you are telling me to do.

Lastly my biggest question is how do I randomize the level sections? So far I understand I need this line to pull the sections from my pool which is successfully happening,

 Pool$$anonymous$$anager.Spawn("Test_Level_Pool_A");

but it’s only pulling one level section, which is my chunk A, how do I randomly pull let’s say Chunk A,B, or C?

Also I Greatly appreciate your help so far.

avatar image VioKyma · Oct 09, 2013 at 09:17 AM 0
Share

Firstly, you will need to add a buffer to your if statment in update eg

 if(objectQueue.Peek().localPosition.y < Player.distanceTraveled + componentBuffer)

This will mean that it will be the buffer's distance ahead of the player in adding components. For the random element, add to the beginning of your script:

 public List<string> levelComponents;

then in the editor, add each of your level component names to the list.

When you want to add a section use:

 if(objectQueue.Peek().localPosition.y < Player.distanceTraveled)
 {
      int randComponent = Random.Range(0, levelComponents.Count);
      Pool$$anonymous$$anager.Spawn(levelComponents[randComponent]);
 }

Coincidentally, do you know where the Pool$$anonymous$$anager will spawn your components?

avatar image Tryflozn · Oct 09, 2013 at 08:07 PM 0
Share

When using this line

 public List<string> levelComponents;

you mentioned that I needed to add the names to a list, How do I do that exactly, do I create a list in the Platform_$$anonymous$$anager script or am I misunderstanding something?

Also I'm not too sure where the Pool$$anonymous$$anager spawns my components how would I find out about that information?

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

17 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to make a endless level generator vertically in 2D? 0 Answers

Random Spawning system? 1 Answer

Managing assets for multiple levels 1 Answer

Procedural level generation for a 3D side-scroller 0 Answers

Level builder for iphone 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges