Simple Tutorial for Pitch Change

This tutorial explains the basics of how to write a simple python script in the Blender Game Engine. It assumes that you know the basics of BGE (check e.g. my tutorial: Your first 3D Game with Blender3D) but, even if you do not, you can follow this tutorial.

Made with: Blender3D v2.62, June 2012

What we’ll get at the end of this tutorial

Through this tutorial we’ll make a simple pitch change effect (also called Doppler effect) which occurs, for example, when an ambulance goes by. However, at the end we’ll got a stationary object (a cube) producing an alarming sound and a movable camera. The velocity of the camera results the change of pitch.

Let’s start

Check the start file

Download this Zip file we need to start (contains a blender file and a “.wav” file):

- Then check what the blend-file includes:

A plane (position: 0,0,0), which represents the ground

A red cube (position: 0,0,1), turning around the Z axis of the world by a motion actuator

A camera (position: 5, 70, 1), to which I assigned some logic bricks, so it could be translated along the Y axis of the world using the arrow keys left and right. Furthermore the camera is tracked to the cube (The Z axis of the camera is always directed to the position of the cube)

And a lamp.

- In the beginning, be sure that you’re in the camera view (press numpad-0).

- Now if you press P (with mouse cursor over the 3D-view), to render switch to play mode, you’ll see a far red cube spinning around the Z axis

- Move the camera nearer to the cube via holding the left arrow key

- You can push the camera in the opposite direction via right arrow

- Escape the play mode by Esc.

Before writing the script

I already added the motion logic bricks to the cube andto the camera. All what we have to do is to add the logic bricks of the sound.

- Select the cube with the mouse (in the 3D view or in the Outliner panel)

- In the logic editor, add a Python controller and a Sound actuator

- Confirm “open” in the Sound actuator and browse the wav-file

- Make a connection between the And controller and the Sound actuator

- In the Sound actuator, switch the “Play Mode” to “Loop End” and check “3D Sound”

The Play Mode “Loop End” of the Sound actuator let the sound file be played continuously in a loop
The function “3D Sound” controls the volume of the played sound relatively to the distance between the audio source (the object which owns the Sound actuator) and the active camera

- Press P to switch to play mode -> Alarming sound should be audible (if not turn your volume up)

- Delete the connection between the And controller and the Sound actuator

- Connect the already existing Always sensor to the Python controller to the Sound actuator ( That makes the Python controller be executed “Always” = in every frame)

- In the Text editor of Blender, create a new script by pressing the button “new” -> Default name of teh script is “text”

- Rename the script to e.g. “pitch.py” by pressing “text”

- In the Python controller in the logic editor, confirm the empty text field and select “pitch.py”

=> Now everything you put in the script will be executed by this controller! So let’s start to script…

Write the script

In this part, I put scripting lines in a frame and I marked with bold the items specific to Blender.

- First of all, import the Blender Game Engine and store its Logic module (This module contains the logic functions) in a variable, just to make it easy to recall

import bge
gl = bge.logic

- Call the function gl.getCurrentController(), which gets the python controller using this script. Store the controller in a variable e.g. “cont” and call its owner (the Cube). Store the Cube object in a variable e.g. cube

cont = gl.getCurrentController()
cube = cont.owner

- That was a way among others to call an object. You can call all the objects of the scene and store them in a list (I gave it the name objectsList) and then pick the object you want. In our case we need the Camera object. Store it in a variable e.g. “cam”

objectsList = gl.getCurrentScene().objects
cam = objectsList["Camera"]

- As we said, the pitch of the sound depends on the instantanious velocity of the camera relativey to the position of the cube. So we need to calculate this velocity in each frame. This velocity equals the distance run by the camera in a frame relatively to the cube.

We can calculate this distance by getting the distance between the two objects (the cube and the cam) in the current frame and subtracting it from the distance between the same objects in the previous frame. Let’s do it in few steps:

. Get the distance between cube and cam in the current frame

dist = cube.getDistanceTo(cam)

. I added a property called “prevDist” to store the distance in the previous frame (it’s actually the distance of the current frame, which has been used to get the velocity and then stored in “prevDist” for the execution of the script in the next frame)

The if-statement in the next script block is used to avoid an error in the first frame, when the prevDist has its default value “0″. If we don’t use this if-statement the prevDist will be 0 in the first frame and subtraction of the distances will lead to a value of the velocity equals to the distance in that first frame.

if cube["prevDist"] != 0:
    prevDist = cube["prevDist"]
else:
    prevDist = dist

. Calculate the instantanious velocity

deltaDist = prevDist - dist

. Store the current velocity to the property “prevDist” to used in the next frame as previous distance

cube["prevDist"] = dist

- In the next few lines we get the Sound actuator connected to the Python controller:

Get the list of actuators connected to the controller

Get the actuator we need from this list

Change the pitch of the Sound actuator to become relative to the velocity (you can experiment with the values of the formula)

FInally, activate the actuator with the new value!

actList = cont.actuators
sound = actList["Sound"]
sound.pitch = deltaDist/5 + 1
cont.activate(sound)
When the cam is not moving => the distance in the current frame is equal to the distance in the last frame => the velocity, which is the difference between those two distances, will be equal to Zero => the pitch is equal to 1 (no modification occurs to the sound)

- Press “P” (with mouse cursor over the 3D view) to see the result!

That was ..

a little tutorial to show you how easy can it be to use Blender3D to simulate such effects.

This script could be used for example in a racing game.

Here you can download a full blender file of this tutorial (I just duplicated the cube and changed the camera tracking)

You may ask “What if I have a game with a switchable camera view, the effect must be disabled…!”.  In this case you may extend this tiny script with an if-statement => If (this camera is active) {perform this effect} Else {set pitch to 1}

If you got any trouble/ like this tutorial/ have an idea, send me an email or leave a comment.

  • You may use these HTML tags: <a> <abbr> <acronym> <b> <blockquote> <cite> <code> <del> <em> <i> <q> <strike> <strong>

  • Comment Feed for this Post
Go to Top