2
\$\begingroup\$

I am looking to implement a means to generate rooms with outer walls with windows and doors from prefab game objects in Unity.

The idea is that a group of tiles is defined as a room which I then iterate through to find the outer tiles and then use their external edges to generate the walls of the entire room. Gathering the outer tiles is easy enough and working out the external edges is already implemented.

What I need to understand is the best approach for using prefab game objects as the set pieces for walls and floors.

Currently for a single wall piece, I have created a quad and made that into a prefab which I then clone, position and rotate into place along the outer edges. The below screenshot shows a room with walls made using the prefab wall GameObject. In this screenshot, the room consists of 12 wall GameObjects. I want to avoid having lots of GameObjects for single wall segments and instead perhaps merge them all into a single mesh on a single GameObject.

generated room

What I would like to achieve is to be able to create a consistent set of pieces for each outer wall, with windows and doors (most likely cloned from other prefabs) to build a realistic looking room. For example, any single length of a wall would be made up from

Wall -> Wall -> Window -> Wall -> Wall

Perhaps there is a much easier way to achieve this that I have overlooked but searching for room generation always leads back to examples for dungeon crawlers and roguelikes. I am not creating a dungeon crawler, nor am I generating the environment proceedurally, instead the player will be able to create rooms in a similar fashion to Evil Genius and The Sims.

In the current approach, creating a room which is 5x5 would mean that there are a total of 20 wall GameObjects and 25 floor GameObjects. I am not keen on having this many objects in the scene for a single room. I would prefer to be able to create a mesh for the entire room, adding in the vertices and triangles from the prefab mesh to cut down on the number of GameObjects in the scene.

Does anyone have any experience with building rooms in this fashion, or are there any clear examples of how to achieve this? I am not sure how to translate and rotate a prefab and then merge the translated meshes into a single mesh. Perhaps I am barking up the wrong tree and there is a better approach but for now, this is the only way I can see which is possible to achieve what I want.

\$\endgroup\$
  • \$\begingroup\$ The visible seams aren't the issue at this point. I'm interested in what approaches I can use to generate the room using prefabs without adding hundreds of game objects to the scene. \$\endgroup\$ – CaptainRedmuff Apr 26 '16 at 17:24
  • \$\begingroup\$ It would help if you could give more info on what you do want - as it stands now all we know is you want A) prefabs & not B) dungeon crawler rooms (though no reasons are given for the latter). Difficult to give / point you to an algorithm if the expected outputs aren't defined. In the mean time, there's this question on procedurally generating houses with rooms \$\endgroup\$ – Pikalek Apr 27 '16 at 14:09
  • 1
    \$\begingroup\$ I have updated the question to remove any ambiguous points and provide examples of other games which implement similar features. \$\endgroup\$ – CaptainRedmuff Apr 27 '16 at 14:26
2
\$\begingroup\$

You can merge the meshes of multiple game objects into one using Mesh.CombineMeshes.

Note that this does not care about which materials you assigned to the input meshes. The GameObject into which you merge the meshes will use whatever materials you assign to its own MeshRenderer. That means when you are merging meshes with different materials, you should use false for the second argument, so you end up with a sub-mesh for each original mesh and then add all the materials to the MeshRenderer of the resulting GameObject.

There is a performance penalty for using the same material multiple times, so you might want to first merge all meshes with the same material with mergeSubMeshes = true and then the resulting meshes with mergeSubMeshes = false.

\$\endgroup\$
  • \$\begingroup\$ As far as i'm aware, merging meshes doesn't take into consideration any translation and rotation applied which would need to be done to move the walls into place. Is there a better approach you can suggest? \$\endgroup\$ – CaptainRedmuff Apr 28 '16 at 8:45
  • \$\begingroup\$ @CaptainRedmuff Retaining the translation and rotation is what the transform field of the CombineInstance structure is for. The example in the documentation demonstrates how to use it: combine[i].transform = meshFilters[i].transform.localToWorldMatrix; \$\endgroup\$ – Philipp Apr 28 '16 at 8:47
  • \$\begingroup\$ Ahhh, I didn't realise that was possible. This sounds like it might be a winning approach. I shall have a look at the documentation and investigate further. Thank you very much. \$\endgroup\$ – CaptainRedmuff Apr 28 '16 at 8:49
1
\$\begingroup\$

Disclaimer - I'm not a unity dev & as such I'm not familiar with all its options, but it does look like it has support for merging meshes together to increase performance.

In general how to tackle this problem will come down to tensions between player freedom, code performance, & development resources:

  • The more you constrain player choice, the easier it is to optimize / special case stuff. I.E. limiting the player to chunky 'room at a time' type prefabs.
  • If you want to give the player a ton of freedom, you may have to allow them to do stupid things - I.E. building a 3x3 room out of wall tiles instead of just using the 3x3 prefab.
  • It is possible to have both high player choice & high performance, but it will likely come at the expense of development time / $ / code sanity.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.