Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
0
Question by Apeinans · May 04, 2016 at 05:29 AM · c#2d gamerandompath

[SOLVED] Problem with random generated path for 2D game

Hello, I am making simple 2D game, something like endless runner(using C#). To make it I am using cube(tile) for random generated path(infinity). Tile have 3 attach(left,right,top) point, so they will spawn to correct place, those attach point is empty game object that is childed to Tile. Using 3 differend prefabs: TopTile, LeftTile, RightTile all of them have same attach points.

Tile Manager script

 public class TileManager : MonoBehaviour {
 
     public GameObject currentTile;
     public GameObject[] tilePrefabs;
 
     private static TileManager instance;
     private Stack<GameObject> leftTiles = new Stack<GameObject>();
 
     public Stack<GameObject> LeftTiles
     {
         get { return leftTiles; }
         set { leftTiles = value; }
     }
     private Stack<GameObject> topTiles = new Stack<GameObject>();
 
     public Stack<GameObject> TopTiles
     {
         get { return topTiles; }
         set { topTiles = value; }
     }
     private Stack<GameObject> rightTiles = new Stack<GameObject>();
 
     public Stack<GameObject> RightTiles
     {
         get { return rightTiles; }
         set { rightTiles = value; }
     }
 
     public static TileManager Instance
     {
         get 
         {
             if (instance == null)
             {
                 instance = GameObject.FindObjectOfType<TileManager>();
             }
             return instance; 
         }
     }    
 
     // Use this for initialization
     void Start () {
         CreateTiles(150);
 
         GameEventManager.GameStart += GameStart;
         GameEventManager.GameOver += GameOver;
 
         for (int i = 0; i < 75; i++)
         {
             SpawnTile();
         }        
     }
 
     public void CreateTiles(int amount)
     {
         //creating new tiles for random generated path (using stacks)
         for (int i = 0; i < amount; i++)
         {
             leftTiles.Push(Instantiate(tilePrefabs[0]));
             topTiles.Push(Instantiate(tilePrefabs[1]));
             rightTiles.Push(Instantiate(tilePrefabs[2]));
 
             leftTiles.Peek().SetActive(false);
             topTiles.Peek().SetActive(false);
             rightTiles.Peek().SetActive(false);
 
             leftTiles.Peek().name = "LeftTile";
             topTiles.Peek().name = "TopTile";
             rightTiles.Peek().name = "RightTile";
         }
     }
 
     /// <summary>
     /// need make condition that tile from current position can spawn only in 2 direction
     /// example, if currect position is LeftTile, then next tile will be left or top
     /// if right, then right or top
     /// if top, only then next tile can be right, left or top
     /// </summary>
 
     public void SpawnTile()
     {
         //generate random number 0-2
         int randomIndex = Random.Range(0, 3);
 
         //condition for checking if there is tiles for path
         if (leftTiles.Count == 0 || topTiles.Count == 0 || rightTiles.Count == 0)
         {
             CreateTiles(100);
         }
 
         //swamping tiles
         if (randomIndex == 0)
         {
             GameObject temp = leftTiles.Pop();
             temp.SetActive(true);
             temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
             currentTile = temp;
         }
         else if (randomIndex == 1)
         {
             GameObject temp = topTiles.Pop();
             temp.SetActive(true);
             temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
             currentTile = temp;
         }
         else if(randomIndex == 2)
         {
             GameObject temp = rightTiles.Pop();
             temp.SetActive(true);
             temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
             currentTile = temp;
         }
         else
         {
             Debug.LogError("Don't have that tile");
         }
     }
 }

Tile script

 public class Tile : MonoBehaviour {
 
 private float fallDelay = 1.5f;
 
 void OnTriggerEnter(Collider collider)
 {
     //condition for tile falldown and spawning next amount of tiles(path) when player enter tile
     if (collider.tag == "Player")
     {
         Debug.Log("Spawn next tile");
         TileManager.Instance.SpawnTile();
         StartCoroutine(FallDown());
     }
 }
 
 IEnumerator FallDown()
 {
     //wait few seconds for doing operation in line below
     yield return new WaitForSeconds(fallDelay);
     GetComponent<Rigidbody>().isKinematic = false;
 
     yield return new WaitForSeconds(fallDelay + 0.5f);
     //"case of" condition for deciding which tiles push in correct stack, disable it and set rigidbody isKinematic to true
     switch (gameObject.name)
     {
         case "LeftTile":
             TileManager.Instance.LeftTiles.Push(gameObject);
             gameObject.GetComponent<Rigidbody>().isKinematic = true;
             gameObject.SetActive(false);
             break;
 
         case "TopTile":
             TileManager.Instance.TopTiles.Push(gameObject);
             gameObject.GetComponent<Rigidbody>().isKinematic = true;
             gameObject.SetActive(false);
             break;
 
         case "RightTile":
             TileManager.Instance.RightTiles.Push(gameObject);
             gameObject.GetComponent<Rigidbody>().isKinematic = true;
             gameObject.SetActive(false);
             break;
 
         default:
             break;
     }
 }
 }

With this code i get randomly spawned tiles, but not something I needed. What i get with this code. alt text

What i wanted to get, but not sure how to implement it. alt text

So far I noticed that i need some condition in function SpawnTIles, but can't figure out how to make it. I want that if there is spawning tiles to left side(for example), then right tiles wont be spawning or something like that. Hope you will help me.

P.S. Sorry for not smart comments in code, I made them to not forget what that code lines do(for myself).

whatiget.png (488.8 kB)
whatiwanttoget.png (279.5 kB)
Comment
Add comment · Show 2
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 Apeinans · May 05, 2016 at 07:54 AM 0
Share

Problem is in SpawnTile

 else if(randomIndex == 2)
          {
              GameObject temp = rightTiles.Pop();
              temp.SetActive(true);
              temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
              currentTile = temp;
          }


Those line, without them it's working almost how i wanted, but without right turn in road.

avatar image Apeinans · May 05, 2016 at 10:50 AM 0
Share

I modified my SpawnTile method to something like that.

 public void SpawnTile()
     {
         int randomIndex = Random.Range(0, 3);
         int spawnIndex = Random.Range(0, 2);
 
         //condition for checking if there is tiles for path if not then creating new tiless
         if (leftTiles.Count == 0 || topTiles.Count == 0 || rightTiles.Count == 0)
         {
             CreateTiles(100);
         }
 
         //spawning tiles
         if (spawnIndex == 0)//spawn tiles to left
         {
             if (randomIndex == 0)
             {
                 GameObject temp = leftTiles.Pop();
                 temp.SetActive(true);
                 temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
                 currentTile = temp;
             }
             else if (randomIndex == 1)
             {
                 GameObject temp = topTiles.Pop();
                 temp.SetActive(true);
                 temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
                 currentTile = temp;
             }
         }
         else if (spawnIndex == 1) //spawn tiles to right
         {
             if (randomIndex == 1)
             {
                 GameObject temp = topTiles.Pop();
                 temp.SetActive(true);
                 temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
                 currentTile = temp;
             }
             else if (randomIndex == 2)
             {
                 GameObject temp = rightTiles.Pop();
                 temp.SetActive(true);
                 temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
                 currentTile = temp;
             }
         }
         else
         {
             Debug.LogError("Don't have that tile");
         }

If comment one of those if statment example(if (spawnIndex == 0)//spawn tiles to left), random path will generate only to left side, same with other spawnIndex if condition, but tiles will spawn to right side. Trying to figure out how to combine them so both will work fine at same time.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Apeinans · May 13, 2016 at 12:35 PM

Add three new variables

     private GameObject next;
     private GameObject nextRight;
     private GameObject tile;
 

And modified my SpawnTiles method to:

 public void SpawnTile()
     {
         int randomIndex = Random.Range(0, 2);
         int rr = Random.Range(0, 2);
         int rrt = Random.Range(0, 2);
         //condition for checking if there is tiles for path if not then creating new tiless
         if (leftTiles.Count == 0 || lTopTiles.Count == 0 || rightTiles.Count == 0 || rTopTiles.Count == 0)
         {
             CreateTiles(100);
         }       
 
         //spawning bonuses
         Bonuses();      
 
         //spawning tiles
         if (tile == currentTile)
         {
             Debug.Log("Left tile");
             //spawn tiles to left or top
             if (randomIndex == 0)
             {
                 currentTile = Instantiate(tilePrefabs[0], currentTile.transform.GetChild(0).transform.GetChild(0).position, Quaternion.identity) as GameObject;
                 tile = currentTile;
             }
             else if (randomIndex == 1)
             {
                 currentTile = Instantiate(tilePrefabs[1], currentTile.transform.GetChild(0).transform.GetChild(1).position, Quaternion.identity) as GameObject;
                 next = currentTile;
             }
         }
         else if(next == currentTile)
         {
             Debug.Log("Top tile");
             //spawn tiles to top with condition parameter which decide to turn right/left
             if (rrt == 0)
             {
                 currentTile = Instantiate(tilePrefabs[1], currentTile.transform.GetChild(0).transform.GetChild(1).position, Quaternion.identity) as GameObject;
                 tile = currentTile;
             }
             else if (rrt == 1)
             {
                 currentTile = Instantiate(tilePrefabs[1], currentTile.transform.GetChild(0).transform.GetChild(1).position, Quaternion.identity) as GameObject;
                 nextRight = currentTile;
             }           
         }
         else if(nextRight == currentTile)
         {
             Debug.Log("Right tile");            
             //spawn tiles to right or top
             if (rr == 0)
             {
                 currentTile = Instantiate(tilePrefabs[2], currentTile.transform.GetChild(0).transform.GetChild(0).position, Quaternion.identity) as GameObject;
                 currentTile = Instantiate(tilePrefabs[2], currentTile.transform.GetChild(0).transform.GetChild(0).position, Quaternion.identity) as GameObject;
                 nextRight = currentTile;
             }
             else if (rr == 1)
             {
                 currentTile = Instantiate(tilePrefabs[1], currentTile.transform.GetChild(0).transform.GetChild(1).position, Quaternion.identity) as GameObject;
                 currentTile = Instantiate(tilePrefabs[1], currentTile.transform.GetChild(0).transform.GetChild(1).position, Quaternion.identity) as GameObject;
                 tile = currentTile;
             }            
         }
     }


I know that it's best solution but still it work how i wanted.

Comment
Add comment · 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

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Distribute terrain in zones 3 Answers

Generate closed, random path in C# 1 Answer

Multiple Cars not working 1 Answer

How do I rotate a 2D object using a joystick? 0 Answers

Zooming in and out with an orthographic camera, while the bottom edge is fixed. 0 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