Search Unity

Building levels?

Discussion in 'External Tools' started by iceshaft07, Jul 23, 2010.

  1. iceshaft07


    Jul 23, 2010
    I come from the old world of Half-life, where I used Worldcraft to build levels where I tediously build every individual box. Nowadays, I've noticed that people are developing worlds using terrains, but this isn't always the best way to create a world.

    What I am getting at, is when you build something indoors, I hardly doubt people are using the terrain generator built in to Unity (not to mention the terrain generator isn't available in Unity iPhone).

    Are you guys using programs like 3D Studio max to build levels? If so, what approach are you using to build colliders (lots of box colliders, mesh colliders) and UVMaps? How would this change if you were developing for the iPhone / iPad?

    Thanks sincererly
  2. hmacyt


    Jul 1, 2010
    Most 3D programs (3DS/maya/XSI/blender) all have great modeling and layer tools which make it easy to UV and create collision meshes. If the floor was simple enough I'd use that mesh for the collider, and for stairs I'd use a rotated plane.
  3. Recluse


    May 16, 2010
    Blender is good for building interiors / exteriors. When the mesh is imported Unity can automatically generate a mesh collider. Nice and easy, once you have learned your way round Blender's UI!
  4. zergmouse


    Jun 30, 2010
    I kind of want to expand on this question and ask what people are doing about creating large scenes?

    Currently I am making a huge very intricate scene with several pipes and ducting along with over 100 valves that I want to be interact able.

    It is much easier for me to make the whole thing as one scene in Maya and import it as a single scene. However since Unity seems to import each object as its own mesh it seems like it would be the same as making several objects and importing them all individually then combining them into one empty game object.

    So is there a difference between one scene with several objects *and* several objects all imported into one scene?

    also, any advice for connecting scripts to a imported model without breaking the prefab? So that I can continue to edit it in Maya while testing scripts.
  5. SteveJ


    Mar 26, 2010
    I second that part. I've got into the habit of just laying out all of my non-interactive objects in my modelling package, then importing into Unity, then adding all the interactive objects (e.g. doors, etc) that have scripts attached, in order to be able to still edit the level without breaking the "prefab".

    Like zergcow, I'd love to know if there's a "better" way in which you can attach scripts etc to parts of an imported scene and still be able to edit that scene in the modelling package, and have your changes reflected in Unity.
  6. w00dn


    Apr 28, 2010
    we tried out a few approaches with importing whole levels from blender and then, with a postprocessor script, assign stuff like colliders, rigidbodies or skripts to them automatically, so the model doesn't loose the prefab connection. but it gets really complicated after a while, when you have to assign 30 different scripts to 30 different objects in a script. but its possible.

    just look for the AssetPostprocessor stuff in the documentation.

    oh, and about the thing with the many level objects vs one single big mesh or several bigger meshes: if you use the same material on some or all of them, you can mark the level as static and it will batch the parts together as good as it can, reducing draw calls quite a lot.
  7. Tysoe


    Jul 6, 2009
    I"m hoping Unity will support some of the new features of .fbx 2011 like instances. If unity does support instances properly it should be possible to have duplicate objects with the same material in your 3D app load as instances of the same prefab in your unity scene.

    Would certainly make level building a lot nicer if you only had to use the unity editor for the last 20% of more gameplay specific editing.
  8. w00dn


    Apr 28, 2010
    i figured, i could post the script we used here. maybe it's of some use to anyone. tested with blender, but should work with the other packages aswell, because it goes for parts of object names. let me know if it works.

    basically, if you put this script into your editor folder, it will modify every import in the folder(s) that contain the word "environment" (changeable in the script). the script goes through the names of all objects present in the file, looking for the following:

    mesh_ -> adds meshcollider
    box_ -> adds boxcollider

    coll_ -> removes meshrenderer (basically a hidden collider. can be combined with mesh_ or box_. very useful if you combined a bunch of smaller objects to one large mesh. you just place another box or simple mesh around that combined mesh and call it something with coll_)
    _r_ -> adds rigidbody
    _rk_ -> adds rigidbody set to kinematic
    _rh_ -> adds rigidbody with a hinge joint
    _ig_ -> removes the object completely (useful for helper objects you don't need imported to unity)

    so for example, you have a level with a floor, a mesh terrain and a crate, rolling down the mesh terrain. you would name the floor "floor_box_", the terrain mesh "terrain_mesh_" and the crate "box_r_"
    then after you import it, you can press play and the crate will roll down the terrain, bumping off the mesh collider and landing on the floor collider.

    after the import, you can tweak the setting. this won't kill the prefab connection, so when you edit the level again in your modelling app, the new objects will appear in the scene and you can tweak their values aswell.

    the skript is also easily extendible. if you for example want to add some script to all rigibodies, you can just extend the script by a few lines and name the object in your modelling package accordingly.

    the only real drawback (for blender users) at the moment is the char-limit on objects in blender. i really hate it, but i'm afraid it's going to stay like that for another wile. (2.5 won't extend the limit :-()

    anyway, here's the script:

    Code (csharp):
    1. class MyModelPostprocessor extends AssetPostprocessor {
    2.     var toDelete = new Array();
    3.     function OnPostprocessModel (g : GameObject) {
    4.         //Debug.Log("Start Postprocessing");
    5.         Apply(g.transform);
    6.         for(go in toDelete){
    7.             assetImporter.DestroyImmediate(go);
    8.         }
    9.     }
    11.     // mesh_ -> meshcollider
    12.     // box_ -> boxcollider
    14.     // coll_ -> removes meshrenderer
    15.     // _r_ -> adds rigidbody
    16.     // _rk_ -> adds rigidbody set to kinematic
    17.     // _rh_ -> adds rigidbody with a hinge joint
    18.     // _ig_ -> removes the object completely from the imported asset
    20.     function Apply (transform : Transform){
    21.         if (assetPath.ToLower().Contains("environment")) {
    23.             if("mesh_")){
    24.                 transform.gameObject.AddComponent(MeshCollider);
    25.             }
    27.             if("box_")){
    28.                 transform.gameObject.AddComponent(BoxCollider);
    29.             }
    31.             if("_r_")){
    32.                 transform.gameObject.AddComponent(Rigidbody);
    33.             }
    35.             if("_rh_")){
    36.                 transform.gameObject.AddComponent(HingeJoint);
    37.             }
    39.             if("_rk_")){
    40.                 transform.gameObject.AddComponent(Rigidbody).isKinematic = true;
    41.             }
    43.             if("coll_")){
    44.                 var mf = transform.gameObject.GetComponents(MeshFilter);
    45.                 var mr = transform.gameObject.GetComponents(MeshRenderer);
    46.                 for(f in mf){
    47.                     assetImporter.DestroyImmediate(f);
    48.                 }
    49.                 for(r in mr){
    50.                     assetImporter.DestroyImmediate(r);
    51.                 }
    52.             }
    54.             if("_ig_")){
    55.                 toDelete.Add(transform.gameObject);
    56.             }
    57.         }
    59.         // Recurse
    60.         for (var child in transform){
    61.             Apply(child);
    62.         }
    63.     }
    64. }
  9. zergmouse


    Jun 30, 2010
    I just posted my code example here if anyone is interested. I have it adding collision objects and scripts. And it is fully commented.

    EDIT: Just wanted to say to the OP thanks for starting this topic. This has been a huge help to me!

    Also, Currently my "level" is around 2 million Verts and it is one maya file and now I am able to import the whole thing preconfigured how I need to just compile the game and run it. Is there any real value in splitting it up into several maya files at this point?
  10. iceshaft07


    Jul 23, 2010
    LOL, no problem-- I didn't quite get the answers I was looking for here, but I just hope that building levels in C4D the same way I build a model is appropriate (I
    m building one large model, and attaching a mesh collider... if a problem arises, I am going to break it up into several meshes with multiple mesh colliders).
  11. Jessy


    Jun 7, 2007
    It's possible, and I initially thought it was a good idea, but it got unusable after using more complex scenes. Here is a version of the approach I took before I abandoned the whole idea. However, there were always way too many bugs with the PostProcessor scripting, so I relied on triggering it all with a menu item.

    I still rely on building colliders in Blender, however. I may improve upon the method later, but despite having to drag and reparent things whenever I remodel a collider (requiring me to remember what I changed or for my partner to document her changes), this is still easier than trying to make colliders in Unity. I also haven't encountered a case where I needed to take the performance hit of a mesh collider.
  12. w00dn


    Apr 28, 2010
    hey jessy

    i'm curious, why did it become unusable after a while?
  13. reset


    May 22, 2009
    Google Sketchup is GREAT for level design - used in conjunction with the new Blender - Blender's will some implement BMESH which will make mesh design even easier in Blender!

    Both are FREE and exceptional!
  14. Jessy


    Jun 7, 2007
    Chiefly, it was because there was no way to just copy a MonoBehaviour, including all its variables as set in the Inspector. Animations also got complex, to the point where, again, it was just faster to propagate changes manually instead of scripting anything, and it's way cleaner to not have to worry about any code, of course.

    I'm not sure what Tysoe is asking for is possible; I use that kind of workflow between Blender projects. As in, I'll instance the same object all over the place. But in Unity, there can be a lot more to an object than just what will transfer via FBX. I'd love to see this kind of workflow become a reality, but as it is, the way that Unity links to an .fbx asset is just shy of useless. You can't even add a script onto one without breaking the connection - doesn't really make for good and easy game creation.

    I showed you what I do for colliders via that wiki link. Aside from that, I've assigned transform copy/paste to three-finger trackpad swipes, so it's pretty fast to get things going, despite being manual. I make all the requisite prefabs, and then copy transforms from fbx objects, in the Hierarchy, delete these objects, and paste prefabs in their place. I've got a third swipe, which is to correct for the stupid axis orientation of Blender, too. :wink:
  15. w00dn


    Apr 28, 2010
    thanks for the infos. i haven't used the approach enough to tell if i can work with it or not, but i can see the limitations. sad but true.
    animations: (yes, i know, documentation says you shouldn't...) what i encountered was, that whenever i had more than one armature object in scene with animations on it, the import of the blend file got really slow. up to minutes even. so i had to separate the animation stuff, like rotating stirrers and swinging stuff and put them back into the level in unity via copy/paste transform. (and fight with the very annoying blender axis rotation stuff ;-)

    looking at the source engine, i was thinking of a way to use text files and store properties in them. like the .qc files (which are used to compile a model for the source engine only..). maybe it would be possible to have a folder with text files in them, named after the object in a scene or something like that and get skripts or their properties on prefabs that way. you could assign materials, set rigidbody values, add sounds, .. the list is endless.
    a skilled one could even write an editor ui for it, so it would be a draggable list.

    i just can't believe we're forced to constantly rebuild stuff by hand. that is a very big error source.

    one last question: is there a reason you prefere fbx export over using one or many blend files?
  16. Jessy


    Jun 7, 2007
    I don't use fbx export; I directly use .blends for everything. But even though the .blend sits in your assets folder, what Unity is really dealing with is an .fbx file that gets exported when you save your .blend and come back to Unity. To see a demonstration of the potential problems with this, if you start getting into Dupligroups in Blender, you'll see that the Project view of the .blend doesn't match up very well with the Outliner in Blender. The way that dupligroups, something we make heavy use of in Blender level creation, are exported via .fbx is just miserable nonsense. (And I told 'em so, and to fix it, here.)

    Another issue is that constraints don't carry over. One problem I have with this is that Blender doesn't allow you to actually parent objects to bones; when you tell it to, it actually skins the other object (which means that Blender is a bald-faced liar, Jerry!). You can use a constraint for the proper effect, in Blender, but that's thrown out in the .fbx. So in Unity, you have to manually move and reparent objects in the Hierarchy, if you need this sort of thing.
  17. w00dn


    Apr 28, 2010
    sounds like a lot of stuff is coming towards me i don't know of yet ;-)

    anyway, thanks for the explanations.
  18. iceshaft07


    Jul 23, 2010
    I am still trying to wrap this around my head, so anyone who can correct me where I am wrong would be great. Also, I apologize for asking so many questions about this, but I haven't found much in the Docs or online about this.

    I have been making my entire scenes in my modelling program. Before I go spending a lot of time building a detailed level I want to confirm my suspicions with you guys (and possibly share some of my old Half-life world building techniques with you).

    Now, lets say you are building a really long hallway of some sort-- even better; Say it is a cave, because that way you can't just use really long boxes in the modelling program.

    Side Note: I have noticed Unity does not like making box colliders for trapazoid shaped boxes. I think these mesh colliders seem the best option for levels.

    Is it better to use one really long mesh to draw the cave, or is it better to divide it up into smaller subsections? (Which one would result in fewer drawcalls)

    Side note: In creating the UV Map for something like a really long cave, I have noticed that the maps I have built don't like having one texture, so my hypothesis is that it is best to divide it up into subsections to get better control of the UV Maps.

    Because the cave is not simply a box, and you want your character to collide along the cave walls, I assume that using a Mesh Collider that is NOT concave is the best option.

    And if I understand that Static checkbox correctly, all level geometry (which does not move) should be set to static-- this should do what I understand is Occlusion culling, which is to say if a triangle can not be seen, it isn't drawn.

    Now, further extrapolating the above statement it is best to have a cave built in such a way to build 'rooms' divided by hallways in the cave-- so, say you have a detailed room in this cave, possibly with stalactites and stalagmites, a beautiful water fall, etc, you might want to build the way into the room L shaped (possibly by putting cargo boxes in from on the room to block the view from when you are all the way down the hall way).. maybe an ASCII picture would help for this one:

    Code (csharp):
    2. *   *
    3. *   *
    4. *   *
    5. *Detailed Hall
    6. *   *
    7. *   ******
    8. *        * <- L shaped hall to separate
    9. ******   *      detailed sections
    10.      *   *
    11. ******   *
    12. *        *
    13. *        *
    14. *Detailed*
    15. *   Room *
    16. *        *
    17. *        *
    18. *   ******
    19. *   *     <- Another L shape to seperate
    20. *   *        detailed sections
    21. *   ******
    22. *     Detailed Hall
    23. **********
    Now, continuing with this cave example, with these stalactites and stalagmites, I have read elsewhere that it is best to use the same material and use the Combine Children on these similar objects to reduce the draw calls.

    Now on the issue with lighting, I understand it is best to 'bake' in lighting into the map (and i have stressed this to my superior). I use Cinema 4d, and I have read very little on this topic; I believe I have read somewhere that Unity provided a plugin to do this? And I think I also read somewhere that only recent versions of Cinema 4d where able to export models with 2 textures (one for a mesh texture, and the other for a light map). If anyone has more info on this, that would be greatly appreciated.

    Continuing on my quest for game design, I also have a question about instantiating bullets.

    I created a game a while back ago that maybe had 50 moving models to create the effect that you were falling down a cave (irrelevant to the above cave). iPhone did not like this one bit (and I understand why, way too many draw calls). I did this by instantiating the models, and then destroying them when they reached the top of the screen.

    My question with the above example, is when I get around to making characters that shoot weapons, I am planning on having anywhere between 6 - 25 characters shooting weapons all at the same time, which instantiates bullet prefabs w/ rigidbodies. How do I go about making all of these character shoot if the iPhone does not like instantiating gameObjects (maybe in the falling game, the models were too much)?

    My understanding of creating bullets is that they can not be combined because they are being instantiated dynamically.

    What is more efficient? Using a trail renderer with a .2 second trail, or using an 8 polygon model for the bullet? Both use a shader with 2 passes.

    I originally wanted to use a physics raycast, to make bullets shoot, but concluded that this is not possible since people want to see bullets-- which must be done with a trail renderer-- which must be done with a moving object.

    Side note: For my bullets, I am using some 64x64 transparent PNGs with Self-Illumin/Tranparent/Cutout. My Unity or Unity iPhone installation I have had that shader for Self-Illumin/Transparent/Cut-Out. Someone generously provided on somewhere on these forums (P.S. Thanks to who did that, I'm using it), and I hope someone looking for a way to make bullets stumbles across this post and saves them time.

    And I guess I want to ask this question while I am at it-- Given the 50 objects, which results in 50 draw calls, each with a rigid body attached, what slows down the game more-- the draw calls, or the rigid bodies?

    Lastly, to all you programmers who have not yet run across EMACS-- go get it. It is the greatest programming editor of all time. Run through the tutorial (it took my 2 hours) and then after 8 hours of using it, you will really begin to appreciate its power.

    I sincerely thank you all for your contributions.[/img]
  19. iceshaft07


    Jul 23, 2010
    I found an answer to many of my questions, and I feel a bit excused since I found this on the manual on my computer and NOT online.

    If you go to Help -> Unity Manual -> Advanced, there is a section on Occlusion culling that I did not find on the online version of the manual (I'm glad I happened to look here, normally I go online).

    The manual states (for the most part):
    Divide up the mesh into rooms (not one big mesh for a cave).
    Use bounding volume game objects for occlusion.

    I would still love an answer to a good way of shooting bullets that won't destroy the frame rate.
  20. AlbertoT


    Mar 27, 2009
    Use 3d world studio
    It costs 50 usd , it supplies only the functions which are really needed for a world editor , one day time to get familiar with
    Last makes the job
  21. tim_bkk


    Sep 22, 2010
    About the bullets, you could figure out the maximum number of bullets that will ever be visible on screen, and Instantiate that number of bullets only and keep them in a Collection.

    Instead of Instantiating and then Destroying a new bullet for each shot, you can just re-use the oldest bullet.
  22. iceshaft07


    Jul 23, 2010
    That seems to be the best way of creating bullets-- I will be making a long forum post about this some point in the future. I'm not sure about how well it will work if a light is also attached to these objects which aren't used, and I am expecting that there will be a slow down at the first shot of a particular gun if the bullet isn't seen by the camera at load of the level.

    But that is definitely for another post.

    Also, for anyone wondering, I posted something about lightmaps and terrain atlases in the Unity Support side of these forums hoping to find some answers. That is definitely relevant to this discussion.
  23. helioraanswer


    Apr 7, 2009

    I have another question about level building. How do you make the borders of your map? Do you script them? Or do you place huge blocks with an invisible texture?
    Or does Unity have invisible volume boxes which are colliders just like in the Unreal Editor?