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 Chocolade · Feb 24, 2017 at 12:59 AM · c#scripting problemscript.maze

How can i make an entrance and exit in this maze ?

The script build a maze but it's close i can move the player inside. I want that each time it's creating the maze it will create a random 2 empty bricks in the outer square like entrance and exit.

So i want to add some public variable so if i change it's value to 1 there will be one entrance and one exit. If i will change the value 3 or to 15 so there will be 3 entrances and 3 exits or if i change it to 15 there will be 15 entrances and 15 exits.

This kind of logic or something like that. And that this entrances and exits will be in a random positions each time i'm running the game.

Another sub question:

I can change now the height and width of the maze. but if i want that all the terrain will be filled with the maze ? for example the terrain resolution is:

Example how the maze looks like now:

Maze

Width = 500 Length = 500 Height = 600

So i want that the maze will be automatic all over the terrain area. The Height should not be 600 but the maze size should be on the terrain size.

 // mazegen.cs
 // remember you can NOT have even numbers of height or width in this style of block maze
 // to ensure we can get walls around all tunnels...  so use 21 x 13 , or 7 x 7 for examples.
 using UnityEngine;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 public class MazeGenerator : MonoBehaviour
 {
     public int width, height;
     public Material brick;
     private int[,] Maze;
     private Stack<Vector2> _tiletoTry = new Stack<Vector2>();
     private List<Vector2> offsets = new List<Vector2> { new Vector2(0, 1), new Vector2(0, -1), new Vector2(1, 0), new Vector2(-1, 0) };
     private System.Random rnd = new System.Random();
     private Vector2 _currentTile;
     public static string MazeString;
 
     public Vector2 CurrentTile
     {
         get { return _currentTile; }
         private set
         {
             if (value.x < 1 || value.x >= this.width - 1 || value.y < 1 || value.y >= this.height - 1)
             {
                 throw new ArgumentException("Width and Height must be greater than 2 to make a maze");
             }
             _currentTile = value;
         }
     }
     private static MazeGenerator instance;
     public static MazeGenerator Instance
     {
         get { return instance; }
     }
     void Awake() { instance = this; MakeBlocks(); }
     // end of main program
     // ============= subroutines ============
     void MakeBlocks()
     {
 
         Maze = new int[width, height];
         for (int x = 0; x < width; x++)
         {
             for (int y = 0; y < height; y++)
             {
                 Maze[x, y] = 1;
             }
         }
         CurrentTile = Vector2.one;
         _tiletoTry.Push(CurrentTile);
         Maze = CreateMaze();  // generate the maze in Maze Array.
         GameObject ptype = null;
         for (int i = 0; i <= Maze.GetUpperBound(0); i++)
         {
             for (int j = 0; j <= Maze.GetUpperBound(1); j++)
             {
                 if (Maze[i, j] == 1)
                 {
                     MazeString = MazeString + "X";  // added to create String
                     ptype = GameObject.CreatePrimitive(PrimitiveType.Cube);
                     ptype.transform.position = new Vector3(i * ptype.transform.localScale.x, 0, j * ptype.transform.localScale.z);
 
                     if (brick != null) { ptype.GetComponent<Renderer>().material = brick; }
                     ptype.transform.parent = transform;
                 }
                 else if (Maze[i, j] == 0)
                 {
                     MazeString = MazeString + "."; // added to create String
                 }
             }
             MazeString = MazeString + "\n";  // added to create String
         }
         print(MazeString);  // added to create String
     }
     // =======================================
     public int[,] CreateMaze()
     {
 
         //local variable to store neighbors to the current square as we work our way through the maze
         List<Vector2> neighbors;
         //as long as there are still tiles to try
         while (_tiletoTry.Count > 0)
         {
             //excavate the square we are on
             Maze[(int)CurrentTile.x, (int)CurrentTile.y] = 0;
             //get all valid neighbors for the new tile
             neighbors = GetValidNeighbors(CurrentTile);
             //if there are any interesting looking neighbors
             if (neighbors.Count > 0)
             {
                 //remember this tile, by putting it on the stack
                 _tiletoTry.Push(CurrentTile);
                 //move on to a random of the neighboring tiles
                 CurrentTile = neighbors[rnd.Next(neighbors.Count)];
             }
             else
             {
                 //if there were no neighbors to try, we are at a dead-end toss this tile out
                 //(thereby returning to a previous tile in the list to check).
                 CurrentTile = _tiletoTry.Pop();
             }
         }
         print("Maze Generated ...");
         return Maze;
     }
 
     // ================================================
     // Get all the prospective neighboring tiles "centerTile" The tile to test
     // All and any valid neighbors</returns>
     private List<Vector2> GetValidNeighbors(Vector2 centerTile)
     {
         List<Vector2> validNeighbors = new List<Vector2>();
         //Check all four directions around the tile
         foreach (var offset in offsets)
         {
             //find the neighbor's position
             Vector2 toCheck = new Vector2(centerTile.x + offset.x, centerTile.y + offset.y);
             //make sure the tile is not on both an even X-axis and an even Y-axis
             //to ensure we can get walls around all tunnels
             if (toCheck.x % 2 == 1 || toCheck.y % 2 == 1)
             {
 
                 //if the potential neighbor is unexcavated (==1)
                 //and still has three walls intact (new territory)
                 if (Maze[(int)toCheck.x, (int)toCheck.y] == 1 && HasThreeWallsIntact(toCheck))
                 {
 
                     //add the neighbor
                     validNeighbors.Add(toCheck);
                 }
             }
         }
         return validNeighbors;
     }
     // ================================================
     // Counts the number of intact walls around a tile
     //"Vector2ToCheck">The coordinates of the tile to check
     //Whether there are three intact walls (the tile has not been dug into earlier.
     private bool HasThreeWallsIntact(Vector2 Vector2ToCheck)
     {
 
         int intactWallCounter = 0;
         //Check all four directions around the tile
         foreach (var offset in offsets)
         {
 
             //find the neighbor's position
             Vector2 neighborToCheck = new Vector2(Vector2ToCheck.x + offset.x, Vector2ToCheck.y + offset.y);
             //make sure it is inside the maze, and it hasn't been dug out yet
             if (IsInside(neighborToCheck) && Maze[(int)neighborToCheck.x, (int)neighborToCheck.y] == 1)
             {
                 intactWallCounter++;
             }
         }
         //tell whether three walls are intact
         return intactWallCounter == 3;
     }
 
     // ================================================
     private bool IsInside(Vector2 p)
     {
         //return p.x >= 0  p.y >= 0  p.x < width  p.y < height;
         return p.x >= 0 && p.y >= 0 && p.x < width && p.y < height;
     }
 }


ss65.jpg (341.8 kB)
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
1

Answer by Patxiku · Feb 24, 2017 at 08:51 AM

Answering to your terrain sized maze question, you could just get terrains size parameters and assign them to your maze height and width (Assuming 1 unit of your maze matches 1 unit of unity):

 //Checking if the terrain size is even, so if it's not the value becomes even
 width = (int)terrainObject.GetComponent<Terrain> ().terrainData.size.x % 2 == 0 ? (int)terrainObject.GetComponent<Terrain> ().terrainData.size.x : (int)terrainObject.GetComponent<Terrain> ().terrainData.size.x + 1;
         heigth = (int)terrainObject.GetComponent<Terrain> ().terrainData.size.z % 2 == 0 ? (int)terrainObject.GetComponent<Terrain> ().terrainData.size.z : (int)terrainObject.GetComponent<Terrain> ().terrainData.size.z + 1;

For the main question, you should define some guidelanes. What do you want your maze behaviour to be?

For example:

-The entrance and exit must be on the outside.

-The entrance and exit must be accesible (have an adjacent nonwall tile).

-The entrance and exit can't be near (define a minimun distance between them).

-If more than one pair of entrance and exit exists, check that entrances and exists don't match in position.

With defined guidelines it should be easy to achieve what you are looking for, just try to reflect them into your code after the maze creation algorithm has finished.

Comment
Add comment · Show 4 · 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 Chocolade · Feb 24, 2017 at 11:05 AM 0
Share

The first part making the maze ins the size of the terrain is working. since it's taking time to build it when running the game i will stay for now with smaller size of the maze as before.

for the second part the main question. If you could guide me how to do it ? Or give me some code start with some simple tutorial how to do it ?

Let's say i want to start to do it the guidelanes in the bottom after the last function IsInside.

How do i start ?

avatar image Patxiku Chocolade · Feb 24, 2017 at 04:46 PM 0
Share

For you have an array that represents the maze, you should be able to follow those guidelines creating rules that apply to the array.

  • "The entrance and exit must be on the border:" For making this possible, you must ensure that the poisition you are trying to instantiate the entrance/exis is either on the i == 0, i ==heightofthearray, j == 0, j == widthofthearray

  • "The entrance and exit must be accesible (have a adjacent nonwall tile)": Just check if any of the positions that are adjacent to the position you are checking is a nonwall, you don't want to have an exit/entrance that is imposible to reach ^^.

  • "The entrance and exit can't be near (define a $$anonymous$$imun distance between them)": You could use the $$anonymous$$anhattan distance algorithm or any other distance algorithms to calculate the values of distance between the entrance and exit and if that value is less than the value you want, deny the exit/entrance creation.

  • If more than one pair of entrance and exit exists, check that entrances and exits don't match in position. Just check if there is any existing exit/entrance in the position you are looking to.

avatar image Bunny83 Patxiku · Feb 24, 2017 at 05:34 PM 1
Share

Since the maze is random the distance check using manhatten distance makes not too much sense. In a maze you can have the entrance and exit right next to each other, but the way you have to walk can be very long depending on the maze structure. So you might need some sort of path finding algorithm (A* for example) to actually trace the path.

I'm also not sure if this maze algorithm ensures an all-connectivity property or if it's possible to have isolated areas. In either way tracing the actual path would certainly be a good idea. A* works on grids like that just fine. However to speed up the search you might want to create a node graph inside the maze and only place nodes at junktions (i.e. places that have more than 2 free neighbors or only 1 or 0 walls around).

edit
It actually should result in a fully connected maze since each path is traced from existing tiles, so they are always connected. So no matter where you place an entrance / exit they will be always connected. Of course to ensure you don't hit a wall you either have to use only odd positions on the border, or check for a wall first.

Ins$$anonymous$$d of A* you can simply use the "always go left/right" method to traverse the whole maze. Using a history stack would allow you to measure the distance directly. Since the maze has no loops you will always traverse the whole maze. So just start somewhere on the border and go ahead. Each step check if the next position is the top of the stack. It it is you're currently walking backwards so you would pop the stack each step. If not you're pushing the current position on the stack. Whenever you reach a "border position" you can simply check the current stack size and you know how many steps you need up to this point. So you can either let it run until you hit a border pos with a large enough distance, or simply let it run through the whole maze and record all distances for all border positions so you can simply pick the largest.

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

297 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Why when creating new animator controller for the character the character is not walking right ? 0 Answers

How can i Instantiate on the terrain from left to right ? 0 Answers

Why the tile map scripts take almost all the cpu usage ? cpu usage is getting to 99% at times 1 Answer

How can i rotate object by pressing on key R and keep object facing to me my self ? 0 Answers

Why it;s never getting to the OnMouseDown function when clicking with the mouse ? 1 Answer


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