Making a 3D Level using Blender
Posted by error454 on 07/14/2010
Since I am a horrible artist, I figured that it would be much easier to model than to draw. For this reason I decided to do my first game in 3D. My game uses a fixed camera view, the camera sits in one place and never moves (except possibly for special effects like camera shake).
Basics
Here is my first level prototype, it doesn’t get much more simple than this.
This 1st-grade style level started raising interesting questions that I didn’t have answers to
- If I want to spawn an enemy, how do I find a specific location on the level surface?
- How can I zoom my camera in so that the level fills the screen?
- How do I zoom the camera in so that you can’t see the enemy spawn location?
- How do I define areas in the level that are special zones, like a Safe Zone where enemies might congregate as part of their AI?
The solution I came up with was to build the level using dummy objects to mark important locations as well as provide a reference for the camera location.
Notice here that there are 3 green cubes, these are dummy objects that won’t be drawn in the game world. The 3 dummy objects shown here are, starting at the left
- PlayerStart
- SafeZone
- EnemySpawn
Here you can see the CamerHelper object, notice how the enemy spawn location is located beyond the bounds of the camera helper.
Naming Objects
Before getting to the code, it is important to name each of my helper objects so that I can find them in the game.
I do this in Blender in the Links and Materials section as shown below, you can see that the Cube.003 object has the name PlayerStart. You change this just by highlighting and typing the desired name.

After naming each helper object, I am finally ready to export my level.
I had a lot of teething issues when I started to export FBX files. I learned a couple rules that are easy to explain by looking at the export dialog. Before I start, I should mention that I always delete the camera and the light in Blender scenes.
- Be sure to select “Scene “Objects” to export all the objects in your scene
- Be sure to Un-Check the Rot X90 button otherwise your model will be rotated by 90 degrees.
- That’s it.
Drawing the level
/// <summary>
/// Draws the specified level, omitting helper objects.
/// </summary>
/// <param name="level">The level object you wish to draw</param>
void DrawLevel(Level level)
{
///Here I am defining a matrix to hold all of the bone transforms.
///A bone transform is simply a Matrix transform that describes
/// how 1 bone is positioned in 3d space relative to the parent
/// bone.
Matrix[] transforms = new Matrix[level.model.Bones.Count];
///Next, I get all the bone transforms that are in my model
/// and I copy them to the transforms Matrix defined above.
level.model.CopyAbsoluteBoneTransformsTo(transforms);
///Lets loop through all the meshes in this level
foreach (ModelMesh mesh in level.model.Meshes)
{
///Don't draw helper objects, so omit anything
///named:
/// CameraHelper
/// PlayerStart
/// EnemyStart
/// SafeZone
if (mesh.Name != "CameraHelper"
&& mesh.Name != "PlayerStart"
&& mesh.Name != "EnemyStart"
&& mesh.Name != "SafeZone")
{
///If we got here it's because the mesh isn't
///one of our helper objects. So go ahead and draw it
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.PreferPerPixelLighting = true;
///This is where the bones come in, we are setting
///the effect's World Matrix to the ParentBone of the
///current mesh.
effect.World = transforms[mesh.ParentBone.Index];
///Set the proper matrices to view what our camera
///is looking at
effect.View = camera.View;
effect.Projection = camera.Projection;
}
mesh.Draw();
}
}
}
Don’t be impressed, I didn’t pull this out of my head, I learned it at creators.xna.com. Once I blindly followed the source, I began to ask my self questions:
Self, what is the parentbone index, what does it represent in the game world?
Well, that is a stupid question, you see ParentBone.Index is just an index that returns the ParentBone. So the question should be "What is ParentBone"? ParentBone is the top level bone that this mesh is attached to, it describes how the current mesh is positioned relative to the parent mesh.
Ok, so you're telling me it's the secret sauce that makes my Blender models look the way I intended them.
Self, why don’t I have to do this for all my meshes?
Ok, didn’t you learn this in gradeschool? The reason you don’t have to do it for your other meshes is because your models were so simple, they were a single mesh and centered at (0,0,0).
Self, why do we assign transforms[mesh.ParentBone.Index] to the World Matrix?
Good question, the 3 matrices of the 3d world are
- World – This matrix describes the location and orientation of a mesh in the 3d world. So if your hero is standing at the end of the platform and is rotated to look at the screen, well, this is the matrix that explains that to your GPU.
- View – This describes the same thing as the World matrix only it is for your camera.
- Perspective – This describes how the camera’s perspective looks, think of it like changing the lens in your camera or zooming in with the camera. There is a difference between zooming the camera and simply moving the camera closer to an object – your field of view changes when you zoom, it doesn’t when you move the camera.
So to answer the question, when we doeffect.World = transforms[mesh.ParentBone.Index];We are assigning the ParentBone (which is simply the top-level bone) transform to the World matrix. We do this because the World matrix describes where in the world our object is. The transform matrix is a matrix that when applied to our mesh, will affect the Position and Rotation of the mesh. By doing so, we will have positioned and rotated the mesh to the same position/rotation in the game world that we so carefully setup in our Blender scene when designing the level.




