Basic Setup in GameBlender
Difficulty Level: Beginner/Intermediate
Requirements: Blender 2.36+
Overview
This tutorial will introduce you to the basics of creating a simple game setup for a game in blender.
Note: This tutorial was written by snailrose a long time ago (around 2004), the days of blender versions 2.36-2.37, so the provided files may not necessarily be backwards compatible with the most current/newest versions of blender. However, the techniques and ideas learned from that can be learned from this tutorial still applies to the current blender game engine. Enjoy
.
TUTORIAL FILES:
- For your convenience, the tutorial files are provided in 2 different compressed formats, you only need to select and download one of them.
I'm going to guide you through the creation if a very basic setup for a game in blender.
1 Adding The Armature
1). Adding The Armature
Position the cursor at the player's center In front view (number pad 1) hit (Space -> Add -> Armature). Make a backbone
With that in place we now need to make some legs. Place the cursor over the top of one of the legs. --Note make sure your in edit mode! (Space -> Add -> Armature). Create three bones (upper, lower, foot) You should now have something like this
2). Mirroring
Leave edit mode (Tab), snap the cursor to the center of the armature (Shift -> S -> 4).
Go back into edit mode. Box Select (B + LMB) the leg Just created.
It will turn Yellow. Duplicate it with (Shift + D) then hit (Esc) Press the (.) key to Rotate/Scale around the cursor.
In front view (Number Pad 1)mirror the selected leg (S -> X -> Enter).
While still in Edit Mode select the top two leg bones.
With them selected go to the Edit Buttons (F9). Look for the drop down menu 'Child Of' and select the backbone. Do this for both bones.
the result
--Note It Is a good idea to name your objects. It prevents confusion later on
3).Vertex Groups
Select the main mesh. Enter Edit mode (Tab).Go to the Edit Buttons (F9) look for the button set 'vertex groups'
Click the 'new' button. In the field that popped up named 'Group'. Change that to the name of the backbone, select the vertices for the body/head and click 'assign'. Do the same for each bone.
--Tip try pressing(L) over vertices and see what happens
--Tip if you need more info on setting up armatures, here is a good resource
4). Parenting the objects
--Tip applying Size/Rot (Ctrl + A) to objects before doing any parenting will prevent issues later on To parent the armature to the mesh. Select the mesh then (Shift + LMB) the armature
and press(Ctrl + P). Choose (Use Armature)
--Note when parenting, select the child object first & the parent object last.
You should now test you setup in Pose mode (Ctrl + Tab), to see if there are any stray vertices anywhere
5). Bounding Box
Set the cursor at the player's center. Add a cube (Space -> Add -> Mesh ->Cube). Scale it to fit the player to make a bounding box. This will be the controller for the logic brick setup Apply Size/Rot (Ctrl + A)
--Note I would like to point out I have the faces on the players mesh with collision set to 'off'in the Paint face buttons...While in face select mode (F)....
If you want to change these settings with meshes containing more than one face you need to press 'Copy Draw Mode' to apply the change to all faces. I have the bounding box do all the calculations The bounding box Must have "'collisions' 'on'"--
In the paint face buttons turn on 'invisible' for the bounding box & Copy Draw Mode. If you enter textured mode (Alt + Z) The bounding box will be invisible.
Now parent the armature to the box (Ctrl + P). If every thing is in place you can drag the bounding box and the child objects will follow. As of now the parenting setup should be 'player mesh -> armature -> bounding_box Go to the Real-time Buttons (F8). Select the bounding box. Press Actor -> -Dynamic look for size->1.000
and change the size ->3.00 to circle the player…
6).The Arms
--The arms will be controlled with a mouse look script-- --Note Who ever wrote these scripts please speak up if you have a problem with me using them-- --Note make sure the '-z' axis on the arms is pointing forward out from the pivot. If it's not place the cursor at the pivot point (Shift -> S -> 4) enter edit mode, select all vertices and rotate them around the cursor until the axis points the way you need it. Leave edit mode and rotate it back the way it was.--
--this way you will get the proper rotation for the arms-- To show the axis for objects, look for the button in the edit buttons (F9)
Add an empty between the head and body. In top view (Number Pad 7), press (Space - > Add -> Empty)& make sure the y-axis points up and the z-axis point's back
Snap the cursor to the empty (Shift ->S -> 4). Select the arms and snap them to the cursor (Shift -> S -> 2).
Now you need to add an ipo to the empty.
Make sure you're on frame one (Shift -> Left Arrow).
Over the 3d window hit (I) and select 'Rot' from the menu. In the ipo window (Shift + F6)you should now see a blue line.
Move the frame from '1' to '200' then rotate the empty 90 degrees so the y-axis points forward. Insert another key frame (I).
Go to frame '400', rotate another 90 degrees. Insert another key frame (I).
Go back to frame 1
(Shift -> Left Arrow) and parent the arms to the empty.
This will be the vertical movement for the arms.
7). Add materials
Add a plane below the player and press (P) You will see that the player bounces on the floor and the arms are not connected to the controller. Parent the empty that controls the arms to the bounding box 'controller'. Select the controller and go to the material buttons (F5), add a new material. Select the button 'DYN'. Set the value restitution to 0 and its friction to 75.
That should get rid of the bounce. Do the same to the plane.
8). Begin the logic
Select the empty and go to the real-time buttons, add a sensor and a controller. Change the sensor to "mouse->movement" and set the controller to "python".
Go to the text window (Shift + F11) and open the script 'HM'&'VM'
Go back to the real-time buttons
Shift select the empty then the arms. Make sure the 'Sel' & 'Link' buttons are pressed
and set them up like this
Add two motion actuators on the arms, name them 'Left' & 'Right'.
Keep in mind; they are case sensitive 'Left is not the same as 'left'
--Note 'Sel' shows logic bricks for selected objects. 'Link' shows logic brick that are attached to the selected item.
The script requires two properties 'move' & 'frame'.
Add an "always" sensor ->"and" controller -> "ipo" actuator. Set the ipo to property and set the property field to call the "frame" property.
Add A "Mouse" -> "movement" sensor & a "python" controller, calling "VM" The final brick setup should look like this
9).Player
I'm going to show you simple python scripting :) Select the players controller In the "real-time buttons" (F8) add a "four" keyboard sensors and "one" controller
The keyboard sensors names and values need to be W, S, A, D; "A" and "D" need pulse mode on... Go to the text editor(Shift + F11) From the drop down menu select "add new" name it "player" ->In the real time buttons add the name of the new script to the python controllers filed
Add "two" actuators that will control our movement by the means of Python. The forward movement will be a "motion" actuator and the rotation will be an "ipo" actuator
Add a property called "rot" set its type to "float"... Add a actuator type->ipo value->property with the field calling the "rot" property. Change its name from "Act" to "Rot" &link it to the python controller... Add a motion actuator name it "move" and link it to the python controller
Select the controller in the 3d view and, go into top view (numpad7). At frame "1" insert a rotation ipo (I->"rot")
Move to frame "10" rotate the controller 90 degrees right and insert another key frame.
Go to the ipo window and select all curves (A) with all curves selected hit this button

You now have a setup to control rotation and movement...
10).Player script
Go back to the text window where you created the script for the player
Add the first lines of code
Player Python Script |
print dir(var) #Example print dir(move) #Check out the console window: functions available for the var: move |
If you press (P) you will see that the player slides everywhere
This can be easily fixed.
In the real time buttons for the controller under 'actor'
Look for 'Damp' & 'Rot Damp' set them to just a little under their max
-notes
if your getting errors with this script
Try removing comments...
make sure sensors and actuators are in the right order in the script.
The functions getSensors() & getActuators() return a list starting at 0
a helpful way to find out how they are arranged in the list
type
print sensors #name of variable assigned to getSensors() function #or print acts #name of variable assigned to getActuators() function |
11).A walk cycle
if you need help with animation in blender--
Go to the action editor(Shilt + F12).
From the drop down menu
select "add new" name it "walk"
-note select the armature and clear parent(Alt + P)
from the "controller"
And Re parent it when you are done with your actions--
Basic->
enter PoseMode(Ctrl + Tab)
Every three frames place key frames at each pose
By, (I) ->"loc Rot"
make a loop by copying the first pose
to the last
--note make sure you have the bones you want to copy, selected--
--Please excuse my poor animation skills :)
add more animations now at will-
putting it into the game
Select the armature then controller.
Go to the real-time buttons(F8) make sure "Sel" & "Link"
Are on
above the logic bricks
Add a controller->ADD and a Actuator->action to the
armature...
Fill the "AC": field with your walk cycle
set its start= 1 & end = 22
Set its type to '
Loop Stop'
connect W -> ADD -> action
do the same for other actions
-- Re-parent the armature to the controller--
--Top--
12). Camera
Add a camera Behind the Player.
Parent it to the controller
if you want good third-person camera tracking do a search
on elysiun.com for 'Bah Cam Bug'..great script
In addition to the third person camera
it would also be nice to have a first person camera
and be able to toggle between the two
Use a simple script for that
place a camera at the tip of the arms
--tip (Ctrl+numPad0) switches between cameras
with the new camera in place
parent it to the arms

1). in the text editor 'add New' name it Cvars
2).Store the cameras values in an empty
Add an keyboard sensor name it 'tab' and set its value to tab
link it to a python controller
add two actuators Scene->Set Camera.
add a propriety int->Cam


Camera toggle#-->basic script stuff import GameLogic as g cont = g.getCurrentController() owner = cont.getOwner() #<-- tab = cont.getSensor('tab') #gets The keyboard sensor 'tab' And assigns it to the name tab acts = cont.getActuators() # gets the camera actuators #split the value of acts into FP TP by the order they are attached to the script starting @ 0 FP = acts[0] TP = acts[1] #the logic if tab.isPositive() and owner.cam == 1: #if tabkey is pressed and propriety cam equals 1 g.addActiveActuator(FP,1) #activate actuator to set the first person camera owner.cam = 0 #assign the cam property to 0 to create a switch elif tab.isPositive() and owner.cam == 0: #if tabkey is pressed and property cam equals 0 g.addActiveActuator(TP,1) #activate the actuator to set the third person camera owner.cam = 1 #set property cam back to 1 |
13). Ammo
Make an empty and place it just above one of the arm ends
--note its important to know which way your axis's are pointing
when you use the Edit Object -> Add Object Actuator
the object being added will be added on the +X axis
make sure the +X axis is pointing up
parent it to the arms
--note being setup this way the +X axis will always point where your arms are
Make the bullet:
Move to one of the higher layers
and add a cube scale it to an elongated triangle and apply size/rot(Ctrl + a)
enter face select(F)->paint face buttons->invisible->Copy Draw mode
name it 'bullet'
14). Smoke
now add a plane in front view(Numpad->1)apply size/rot(ctrl+a)
hit the axis button then
enter face select mode(F)see how one side is invisible:
that side needs to face the -x axis
enter edit mode and rotate it accordingly go
into the uv editor(Shift + F10) and select a smoke texture
go to the face paint buttons and select 'halo' & 'ADD' & 'ObColor' turn off collision
Making the smoke texture fade...
go to the ipo window and LMB the 'ColA' then go over
to the grid and (Ctrl + LMB) to start a curve
enter edit mode in the ipo window and select one curve
and press(N) set LocX & Loc Y to 1.0 select the second one and set it to LocX 10 &
LocY 0
repeat the same steps for ColR, ColG, ColB..
in the realtime buttons under the smoke object add the following
select the bullet and go to the realtime buttons add the following bricks
Go back to the layer where the player is. Hide the bullet and smoke objects
select the "add object empty" above the arm and add the following bricks
do the same thing for the other arm or the you could duplicate the empty and change it's trigger to RMB
15).Boom
create a ground plane for the player to move around on
Make a bounding box -arena type thing for a boundary
set it to invisible
Add another cube. This ones to shoot at...
texture it
in the realtime buttons for the box set it
like so
instead of using python for the box here is a simple way to
keep track of hits...
With the cube selected go to realtime buttons
add a property int->'hits'
select the bullet and add a property Bullet
add the logic like this
that will end it but what about an explosion
do that the same way you did the smoke and set it up
so that when property hits = 4, use an edit object actuator
to add a explosion
16).display
open up your favorite paint program
and create a target on a black background
1). Add a plane and add the target texture to it
in the paint face buttons set from 'opaque' -> 'add' & 'collision off'
2). set it in the middle of the first person camera, and
scale it down to a nice size, parent it to the first person camera
3). rotate the triggers that add the bullets about 3.00 degrees inward
4). The target needs to be invisible when in third person view
a very simple way is to copy the property
"cam" from the empty that holds its value -
>select the target & in the realtime buttons
create a property named 'copy cam'
add this logic brick setup

then...
if copy cam equals one(third person) make it invisible
if copy cam equals zero(first person) make it visible
now the target should be only visible in first person mode
17).Modify the mouse look
There is a problem---
When you switch to first person view the arms need to turn the body --
to fix this you will need to rig the mouse look script to handle this.
1) . add an always sensor->pulse mode "OFF" and link it to the empty that holds the cameras value
go to the "Cvars" script and add the following code
(g.cam = owner.cam) #Turn the camera value into a global var(accessible by any script) name 'cam' |
2) .in the players Logic bricks add two motion Actuators
Named 'myLeft, myRight'
Link them to the "HM" script
then change the 'HM' script as follows
#get actuators RightMove = Cont.getActuator('Right') LeftMove = Cont.getActuator('Left') myLeft = Cont.getActuator('myLeft') #<-- add this line myRight = Cont.getActuator('myRight') #<-- add this line if cam == 1: #<-- add this ststement if (Xpos > Width): XDiff = Xpos - Width RightMove.setDRot(0,(XDiff /Own.move),0,1) addActiveActuator(RightMove,1) if (Xpos < Width): XDiff = Xpos - Width LeftMove.setDRot(0,(XDiff/Own.move),0,1) addActiveActuator(LeftMove,1) #------------------> add this if cam == 0: if (Xpos > Width): XDiff = Xpos - Width myRight.setDRot(0,0,(XDiff /Own.move),1) addActiveActuator(myRight,1) if (Xpos < Width): XDiff = Xpos - Width myLeft.setDRot(0,0,(XDiff/Own.move),1) addActiveActuator(myLeft,1) #<-------------------- addActiveActuator(LeftMove,0) addActiveActuator(RightMove,0) addActiveActuator(myLeft,0) #<-- add this line addActiveActuator(myRight,0) #<-- add this line |
--note intention of the code does matter if its not properly indented you will get a error in the console--
3). add an inner if statement to the players script
this is to shut off the 'A,D' rotation
-change it as follows
if (A.isPositive()): if g.cam == 1: #<-- if were not in first person view owner.rot -=0.1 #<--do the normal a,d rotation g.addActiveActuator(rot,1) g.addActiveActuator(rot,0) #<- if were in first person shut off a,d rotation elif(D.isPositive()): if g.cam == 1: owner.rot +=0.1 g.addActiveActuator(rot,1) g.addActiveActuator(rot,0) |
18) AI
--I have included a blend file with an enemy in it but feel free to use your own
-note it will be best to set the bullet to "ghost" but make sure collision is on in the paint face buttons... collisions will still work, and the enemy wont fly everywhere
1). append all objects from e_base.blend
2). create a script for your enemy
Set up an always sensor on the enemy controller and call the newly created script
1). Set up some base controllers & actuators
You need a
collision ->sensor
ipo ->actuator
motion ->actuator
for the collision sensor select the ground plane and add a property called "ground"
and go back to the controller for the enemy and add a collision sensor
and in the property field set it to "ground"
add a motion actuator and name it "move" an link it to the python script.
add a property named rot .
then add a ipo actuator calling "rot" just created
&,connect it to the script
- note the enemy has the same basic setup as the main char you now have some basic bricks in place to run some tests
2) . on to the script first thing that needs to be done is import the GameLogic module the controller &the owner
--like so
import GameLogic as g c = g.getCurrentController() o = c.getOwner() |
-->now get the sensors connected to the script with the getSensors() function
sensors = c.getSensors() |
run a test type --- print sensors --- and you"ll see the names of the sensors connected...
now you need to get the collision sensor, which I named "col". To get it you would use...
col = sensors[1] |
the array starts a zero so the second connected sensor will be [1]
You now have the collision sensor which is assigned to the variable col
now do the same for the actuators using the getActuators() function
acts = c.getActuators() move = acts[0] rot = acts[1] |
Use an if statement to make it move
-basic: if col->sensor is positive... add the motion actuator
if col.isPositive(): move.setLinearVelocity(0,8,0,1) #<--set the linear velocity x,y,z, 1 or 0 g.addActiveActuator(move,1) #activates the motion actuator |
what if you want to have it move for a specific amount of time and then turn? add a property in the controller for the enemy call it "count"
with the newly added property you can use python to access its value and change it with "owner.prop" which is "o" in this case
hit the debug button "D" by the property...
Now when you press play you now can see the debug info add the following line...
o.count += 0.01 |
f you press play you can see that the value is incremented (+= value)
you can use that to set a condition using the <, >, <=, >=, symbols..
--type
if o.count >= 1: o.rot +=0.1 # increment the rotation property g.addActiveActuator(rot,1) #Activate rotation |
Now send it into a cycle add the following
if o.count >= 1 and o.count <= 3: o.rot +=0.1 # increment the rotation property g.addActiveActuator(rot,1) #activate rotation ipo elif o.count >= 6: # if count is greater or equal to six o.count = 0 #set it back at 0 |
if you press play now you can chase the enemy around this will be a base for what comes next
select the enemy armature then it"s controller ...
In the realtime buttons... ...
ADD -> action under the armature & set it to loop stop
In the AC: field type "run" then set the start & end frames
Link it to the python script
In the script, go to where you got the actuators... Add this line.
run = acts[2] |
you now have the action to use via the script go to the statement -->if col.isPositive() and add this line below
g.addActiveActuator(run,1) |
the action should play and the enemy should now run in circles
With that finished its time to build some states...
One where the enemy will run back and forth, "like you just did",
and another for an attack
here is the method I"m going to show you
Define a function with the statement
def func_name(arg): do stuff... return arg |
then you can control a whole lot of code with
func_name(arg)
The first function is almost already made
change the script to this
#these two variables are to start and stop the function # for example func(x) = start func(y) = stop x = 1 y = 0 def pace(x=y): #define the function global y #make y accessible within the function # x equals one if we start the function with x, so execute the script untill the else statement if x == 1: if col.isPositive(): #then take the same logic outline above move.setLinearVelocity(0,8,0,1) g.addActiveActuator(move,1) g.addActiveActuator(run,1) o.count += 0.01 if o.count >= 1 and o.count <= 3: o.rot +=0.1 g.addActiveActuator(rot,1) g.addActiveActuator(run,1) #set run active if o.count >= 6: o.count = 0 else: # if the function is start with y the code above does not run y = 0 return x,y |
#test it out -- pace(x) or pace(y)
set that code aside and get an attack state going
the enemy needs to be rigged the with attack sensors.
1). add an empty in front of the enemy with x-axis forward & parent it to the enemies controller
select the controller then the empty & add a edit object Actuator under the empty
Link it to the ai python script
set it"s field to call the bullet
-add the following line of code to the list of actuators
bul = acts[3] |
2) select the player and add a property called "player"
go back to the enemies controller and add a near sensor and set its field to "player"
set its dist to about 10 and its reset at 25 attach it to the python controller..
add the following line of code under the controller list
near = sensors[2] |
you should be set now to do some scripting add the following
if near.isPositive(): # if the near sensor is triggered g.addActiveActuator(bul,1) #fire the bullet #the shots need to be spaced out... for that use the count property o.count +=0.01 # increment the count property # if the near sensor is positive and count is between the two values if near.isPositive() and o.count >= 1 and o.count <=1.1: g.addActiveActuator(bul,1) # fire the bullet if o.count >= 4: o.count = 0.0 #reset the count property to zero |
now go back to the controller for the enemy and add a edit object -> track to the players_controller add the new actuator to the script
track = acts[4] |
then activate the the actuator -add the following
if near.isPositive(): g.addActiveActuator(track,1) |
-now put it together
#--> o.count +=0.01 if near.isPositive() and o.count >= 1 and o.count <=1.1: g.addActiveActuator(bul,1) if o.count >= 2: o.count = 0.0 if near.isPositive(): g.addActiveActuator(track,1) move.setLinearVelocity(0,6,0,1) g.addActiveActuator(move,1) g.addActiveActuator(run,1) else: move.setLinearVelocity(0,0.01,0,1) g.addActiveActuator(move,1) #<-- |
that should be a simple enough attack... wrap it in a function like the one before same basic principal
def atx(x=y): #define the function global y o.count +=0.01 # increment the property count if x == 1: if near.isPositive() and o.count >= 1 and o.count <=1.1: g.addActiveActuator(bul,1) if o.count >= 2: o.count = 0.0 if near.isPositive(): g.addActiveActuator(track,1) #track to the player move.setLinearVelocity(0,6,0,1) #set a forward movement g.addActiveActuator(move,1) #activate movement g.addActiveActuator(run,1) #activate action else: move.setLinearVelocity(0,0.01,0,1) #stop g.addActiveActuator(move,1) #activate g.addActiveActuator(track,0) #stop the track else: y = 0 return x,y #test it atx(x) or atx(y) |
now put them together -basic: if the player is near the enemy the atx() function will be activated if not the function pace() will be active heres how
if near.isPositive(): atx(x) pace(y) else: atx(y) pace(x) g.addActiveActuator(track,0) #stop track g.addActiveActuator(move,0) #stop lose movement |
Final AI scriptimport GameLogic as g c = g.getCurrentController() o = c.getOwner() sensors = c.getSensors() col = sensors[1] near = sensors[2] acts = c.getActuators() move = acts[0] rot = acts[1] run = acts[2] bul = acts[3] track = acts[4] x = 1 y = 0 def pace(x=y): global y if x == 1: o.count += 0.01 if col.isPositive(): move.setLinearVelocity(0,6,0,1) g.addActiveActuator(move,1) g.addActiveActuator(run,1) if o.count >=1 and o.count <=3: o.rot += 0.1 g.addActiveActuator(rot,1) elif o.count >=6: o.count = 0 else: y = 0 return x,y def atx(x=y): global y if x == 1: o.count +=0.01 if near.isPositive() and o.count >=1 and o.count <=1.01: g.addActiveActuator(bul,1) if o.count >=4: o.count = 0 if near.isPositive(): move.setLinearVelocity(0,6,0,1) g.addActiveActuator(move,1) g.addActiveActuator(track,1) g.addActiveActuator(run,1) else: move.setLinearVelocity(0, 0.01, 0, 1) g.addActiveActuator(move,1) g.addActiveActuator(track,0) g.addActiveActuator(run,0) else: y = 0 return x,y if near.isPositive(): atx(x) pace(y) else: atx(y) pace(x) g.addActiveActuator(track,0) g.addActiveActuator(move,0) |
its pretty stupid AI but the method works for more complex stuff
some stuff that needs to be added is, sensors on the enemy to detect walls and other objects, scores, more animations......
-- This might not be the best way to make a game in blender its just my method..
I hope you enjoyed reading it & it has not raised more questions than it has answered--
I know my writing skills are terrible, so feel free to tell me to go buy an english book :) snailrose...
Last Updated (Sunday, 13 July 2008 23:32)


