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 seandolan · Jul 08, 2018 at 03:06 AM · 3dwallsoptimisation

How to draw walls around rooms using the least number of objects for walls?

I have created a new project to test in before I implement it into my game. Essentially my end game will have a series of rooms. I want to generate all the walls around each room via code. I would really appreciate some help in working this problem out. The current code I have does the follow:

1. Randomly generate a floor tile from 1 to 3
2. Place an coloured object to indicate the floor tile's number
3. Place a along wall on the north, south, east and west sides of the base cube
4. Loop through each tile and work out if the one before (either in x for horizontal, or y for vertical) and place a wall if the tile before is different than the current one.

What I want to do to optimise this all is only use a single object for continuous sides. For example: In the current code, a wall may consist of 3 single wall items in a row one after the other. I want it to just make 1 wall instead to replace these 3 walls.

So basically optimising it this way:
Example of desired changes

Here is what my current setup looks like:
Current setup



And here is the code I have for the above current setup:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Walls : MonoBehaviour {
 
     int[,] tiles;
     public GameObject wall;
     public Transform walls;
 
     public GameObject floor1;
     public GameObject floor2;
     public GameObject floor3;
     public GameObject floor;
 
     public int width = 30;
     public int height = 30;
 
     void Start () {
         tiles = new int[width,height];
         GenerateTiles();
         GenerateWalls();
     }
 
     void GenerateTiles() {
         for(int x = 0; x < width; x++) {
             for(int y = 0; y < height; y++) {
                 tiles[x,y] = Random.Range(1,4);
             }
         }
     }
 
     void GenerateWalls() {
         Vector3 horizontal = new Vector3(0,0,0);
         Vector3 vertical = new Vector3(0,90,0);
         GameObject northWall = Instantiate(wall,new Vector3(0,-0.5f,(height / 2)),Quaternion.Euler(horizontal),walls);
         northWall.transform.localScale += new Vector3(width - 1,0,0);
         GameObject southWall = Instantiate(wall,new Vector3(0,-0.5f,-(height / 2)),Quaternion.Euler(horizontal),walls);
         southWall.transform.localScale += new Vector3(width - 1,0,0);
         GameObject eastWall = Instantiate(wall,new Vector3((width / 2),-0.5f,0),Quaternion.Euler(vertical),walls);
         eastWall.transform.localScale += new Vector3(width - 1,0,0);
         GameObject westWall = Instantiate(wall,new Vector3(-(width / 2),-0.5f,0),Quaternion.Euler(vertical),walls);
         westWall.transform.localScale += new Vector3(width - 1,0,0);
         for(int x = 0; x < width; x++) {
             for(int y = 0; y < height; y++) {
                 if(tiles[x,y] == 1) {
                     GameObject newFloorTile = Instantiate(floor1,new Vector3(x - (width/2) + 0.5f,-0.5f,y - (height/2) + 0.5f),transform.rotation,floor.transform);
                 }
                 if(tiles[x,y] == 2) {
                     GameObject newFloorTile = Instantiate(floor2,new Vector3(x - (width / 2) + 0.5f,-0.5f,y - (height / 2) + 0.5f),transform.rotation,floor.transform);
                 }
                 if(tiles[x,y] == 3) {
                     GameObject newFloorTile = Instantiate(floor3,new Vector3(x - (width / 2) + 0.5f,-0.5f,y - (height / 2) + 0.5f),transform.rotation,floor.transform);
                 }
                 if(y != 0 && y != height) {
                     if(tiles[x,y-1] != tiles[x,y]) {
                         GameObject xWall = Instantiate(wall,new Vector3(x - (width / 2) + 0.5f,-0.5f,y - (height / 2)),Quaternion.Euler(horizontal),walls);
                     }
                 }
                 if(x != 0 && x != width) {
                     if(tiles[x - 1,y] != tiles[x,y]) {
                         GameObject yWall = Instantiate(wall,new Vector3(x - (width / 2),-0.5f,y - (height / 2) + 0.5f),Quaternion.Euler(vertical),walls);
                     }
                 }
             }
         }
     }
 }

walls.png (385.8 kB)
walls2.png (9.4 kB)
Comment
Add comment · Show 4
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 JVene · Jul 08, 2018 at 03:28 PM 0
Share

I'm in drive by mode (quick 'n dirty), so I'm going to avoid C# example code.

I'd consider a schematic, possibly implemented as an array of objects. I personally prefer simple arrays for this, ins$$anonymous$$d of 2D arrays, where row(n) is array + ( n * rowWidth ), but each to their own. For this requirement, I'd consider each "cell" of this structure to represent where a wall $$anonymous$$IGHT go, not where a tile might go.

In this parlance, I'll say walls are horizontal (for the row) and vertical (for the column), viewed from the perspective of a board game.

As walls are formed by your current method, I'd note where a wall is in the array (which, by definition, means those I don't touch have no wall).

Then, I'd run through rows first (columns in a second pass), and check each cell. I'd count the number of contiguous cells with wall structure, then fashion the wall object based on that size. For the rows I'd assume the creation of horizontal walls.

This means you'd collect the incidental situations where walls form long chains without regard to actual color boundaries, so you can end up with walls optimized beyond the color assignments, which may be of benefit.

If the squares are, say, .25 each side, you'd have to consider how you want to deal with margins for the space of the wall to calculate the size of the wall. For example, if the thickness of the wall is .025, and you find 3 cells in sequence with a wall structure, you'd have 3*.25 + 2*.025 in total length, assu$$anonymous$$g you don't $$anonymous$$d the implied alignment of these horizontal walls.

I'd run a separate pass for vertical walls.

This method allows you to place walls using the existing method, then sweep through to "merge" individual wall segments into longer wall segments.

It assumes you prefer to create rectangular objects as walls, rather than create meshes.

If you created meshes, you could theoretically fashion one wall object that turns 90 corners, but the complexity may not be worth it.

avatar image seandolan JVene · Jul 09, 2018 at 05:44 AM 0
Share

Thank you for your reply. The size of the objects isn't a problem. They are set how I want them already. The current code works to generate a single wall where they should be. I do appreciate your comment but it really only reiterates what I am trying to achieve, not really how to calculate it. I can count how many tiles came before hand that needed a wall. I can calculate how long the wall needs to be. The problem is that I can't work out how to offset where that wall should be located accurately.

avatar image JVene seandolan · Jul 09, 2018 at 06:22 PM 0
Share

"The problem is that I can't work out how to offset where that wall should be located accurately." I've hinted to that with "... you'd have 3*.25 + 2*.025 in total length...", but I didn't detail it assu$$anonymous$$g that since you've already placed tiles that wouldn't be an issue. Before I continue, I'd like to point out that I'm not sure if you have a clear sense of scale with respect to physics, if physics is part of your game. This layout is large. If I read this correctly, the playing field is 30 x 30 units, which means with respect to physics that's 30 meters by 30 meters, or some 98 square feet. If a .5 meter sphere were tossed in as a ball, the physics would look very slow - though that $$anonymous$$IGHT be an intent, I don't know. A .5 meter ball is a "beach ball" size, which has a certain "look" with regard to how fast it falls and moves. If objects should react more like baseball sized objects (which, relative to their size, should appear to fall much faster, A baseball would be .074 (just under 3 inches) in diameter. I say this because in most work I'd expect to see some indication of the size of objects such that the code used to create the field would work on any sized objects, not specifically sized objects, especially under the assumption of aligned units (that is, typically, things are created as 1, 2 or 3 units in size, which is meters. Setting that aside, there are some specifics that must be nailed down. I personally prefer to think in terms of a corner, but it appears you like to think about the center of objects for placement. I'll work with center placement. The square has a dimension, say sd. The center of any square would be sd/2, so the dimension is the side of a square. The wall has a width, say sw, which might be a fraction of the square size, perhaps sd/10 or sd/20. A schematic of the field would be indices into a 2D array structure, which I infer from tiles[x,y], such that the 4th tile of the 3rd row is tile[3, 2] if x are columns and y are rows . If I assume that there is no space between tiles, and the wall straddles the join between tiles, and the floor is the xz plane, a tile is located by it's center with tile_center_x = ( sd x ) + ( sd / 2 ), tile_center_z = ( sd y ) + ( sd / 2 ), which implies that the upper left corner of the tile is ulc_x = tile_center_x - ( sd / 2 ), ulc_z = tile_center_z - ( sd / 2 ), and the other corners can be deduced with something like urc_x = ulc_x + sd, urc_z = ulc_z, llc_x = ulc_x, llc_z = ulc_z + sd, etc. A wall starts at a corner, perhaps centered on the line of the tile. A horizontal wall might be placed by finding the upper left corner of the first square and the upper right corner of the last square in a sequence. The wall's 2d placement would then account for the wall's width (sw), itself a rectangular solid. You already have in $$anonymous$$d the wall's height (which I'd suggest be swh = sd / 2, or something expressed in terms of the size of the square, but that's up to you). (continued...)

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by DawdleDev · Jul 09, 2018 at 06:39 PM

Here's an idea for an algorithm. While the code is recording a stretch of walls facing in the same direction, record the number of walls being placed in an integer. Once you get to a place where the walls turn, erase all of the walls placed. Then, create a new wall that is the length of each wall multiplied by the number of walls, at a position halfway down the line of walls.

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

99 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

Related Questions

Running on Walls making my movement weird 0 Answers

How do you calculate walls between tiles in a 3d environment? 5 Answers

how can i manually update unity web player ? 0 Answers

Raycast shooting in the middle of the screen 0 Answers

How to add to a 3D object's length through code? 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