FPS Mouselook Script Plus Real Text in the Game Engine

Posted by Chris Plush on July 17th, 2014 | Comments (30)


Tested as of 2.71. Later versions may need “import bge” added to the top of your scripts. Later versions also have a new mouselook actuator that would replace some of this tutorial.


Table of Contents:

  1. Mouselook Script and Realtime Text – Introduction
  2. Using the Mouselook Script
  3. Running the Script in Your Game
  4. Adding Realtime Text
  5. Changing the Font Resolution
  6. Customizing Your Font
  7. Adding Text to Your HUD
  8. Word Wrapping
  9. Extra: More Text Formatting
  10. Conclusion

Mouselook Script and Realtime Text – Introduction

Did you know that Blender’s game engine has support for real font? If we catch you still using bitmap fonts you’ll be put in stocks in the town square and have tomatoes thrown at you. This tutorial was originally just going to be a simple one on creating realtime text, but in putting together a quick demo level for it I also created a mouselook script I would like to offer everyone. For those of you unfamiliar with the term mouselook, it refers to using mouse movement to rotate the camera and look around the scene. This is typical of first person shooter type games. I should note right off the bat that you don’t need to know anything about python to do this tutorial or to use any of the scripts involved.

After we work with the mouselook script we’ll get into adding realtime text. Here we’ll deal with adding text, changing the font resolution, changing the text value in a game, and formatting the text. Formatting will include basic string operations but most notably we’ll learn how to word wrap text. Word wrapping refers to splitting long lines of text into separate lines based on line length, something that was difficult with bitmap fonts but is really simple now that real font is supported. Below is a screenshot of the scene we’ll be working with towards the end of the tutorial.

Click image for full size

Using the Mouselook Script

You can download a simplified mouselook example file here

The script is super simple to use, and includes camera angle limitations so the camera stops rotating when you’re looking straight up or straight down. This angle range can be easily changed too.

Now you can either reverse engineer that scene to understand it, import the objects into your scene, or follow these instructions to learn how to implement it on your own. First, here’s the actual script itself. If you’re implementing this into your own scene, simply paste the following code into a new text document in Blender’s text editor, and name it something like “mouselook.py”.

from bge import render as r
import math

cont = bge.logic.getCurrentController()
own = cont.owner
mouse = cont.sensors["Mouse"]
parent = own.parent

#set speed for camera movement
sensitivity = 0.05

#set camera rotation limits
high_limit = 180
low_limit = 0

h = r.getWindowHeight()//2
w = r.getWindowWidth()//2
x = (h - mouse.position[0])*sensitivity
y = (w - mouse.position[1])*sensitivity

if own["startup"]:
    r.setMousePosition(h, w)
    own ["startup"] = False
    rot = own.localOrientation.to_euler()
    pitch = abs(math.degrees(rot[0]))
    if high_limit > (pitch+y) > low_limit:
        pitch += y
    elif (pitch+y) < low_limit:
        pitch = low_limit
    elif (pitch+y) > high_limit:
        pitch = high_limit
    rot[0] = math.radians(pitch)
    own.localOrientation = rot.to_matrix()

    parentRot = parent.localOrientation.to_euler()
    yaw = math.degrees(parentRot[2]) + x
    parentRot[2] = math.radians(yaw)
    parent.localOrientation = parentRot.to_matrix()

    r.setMousePosition(h, w)

Running the Script in Your Game

In short all you have to do is run the script from a camera which is parented to your main character. Also give the camera a boolean property called “startup” set to True. That’s all. The script rotates the camera but also rotates the object it’s parented to so that your main character is facing the same direction the camera is. So when you open that example file you’ll see the camera running the script from a mouse movement sensor and an always sensor(set to true pulse). This camera is parented to my main character(which is a cube) which also has typical FPS movement controls. To be safe, make sure your main character’s Z axis is pointed up. Check out the images below for the different settings for both the cube and the camera and then let’s move on to text in the game engine.

Settings for the Camera:

Settings for the Cube:

Adding Realtime Text

Blender uses the Text objects for realtime font. It renders them as real font when you start the game. So start a new scene and go into camera view. Left click near the upper left corner to place the 3d cursor there. Now press Shift+A and add a Text object. We went into camera view before adding the text so the text would be facing the camera. If your text isn’t facing the camera, go to the Editing tab in the User Preferences and change the Align To option to View. That way any objects you add will be aligned to the view instead of the world axis. It’s worth noting that you can rotate and scale the text however you want and it’ll still render skewed like that in the game though, which is awesome. Now press P in the 3D View.

Changing the Font Resolution

There you have it. You may notice the font is a little pixelated though. We can fix this in two ways. You can either move the text object further from the camera(and scale it up as needed) to sharpen it, or create a python script to change the resolution. So let’s make that script now. Go to the Text Editor in Blender and create a new file called “text_res”. Paste in the following code:

cont = bge.logic.getCurrentController()
own = cont.owner
own.resolution = 5

Now with the Text object still selected, go to the Logic Editor window and add an Always sensor connected to a Python controller. Click on the script field in the controller and select “text_res”. Press P in the 3D View again. No more blurry text! Change the resolution value until your text looks good. Don’t go too high. High values run the risk of freezing things up as Blender tries to make your text a needlessly high quality. A value of 1 is default, so start at 2 and go from there.

Logic Bricks setup:

No more blurry text:

Customizing Your Font

You can change the font color by changing the object color. To do that, go to the Object properties(cube icon in the Properties window) and change the Object Color option. To change the font, go to the Font properties(F icon in the Properties window) and load in different fonts there.

Adding Text to Your HUD

Now that we know how to add and customize text, we’re going to work with a real game and create an overlay scene which will show us messages and HUD elements like health or ammo. The initials HUD stand for Heads Up Display, and shows the player valuable information about their character like health, score, and ammo. Here we’ll also learn how to format the text and word wrap long strings(in coding text is referred to as strings). We’ll also learn how to change the text dynamically in game using both logic bricks and python.

Download the game level start file here

When you open up the file, you’ll notice it already has the cube and the camera from the mouselook blend. I’ve also added a walk and crouch animation on the camera and cube to make movement more interesting. Also note that in the render settings I have the animation frame rate set to 60 for smoother animations. So the scene is ready to play. Press P to roam around. Use WSAD to move and tap CTRL to crouch. Collect the ammo box in middle of the level. Our goal right now is to add an ammo counter to a HUD that increases with every ammo box you pick up. So first let’s create the overlay scene that will have the HUD. Create a new scene by going to the top header in Blender and clicking the + sign next to the scene field. Then select “New”.

Rename this scene to “HUD”. Go in to front view and add a camera. In side view move this camera to the left away from the world origin. Now back in camera view add a Text object and position it in the upper left of the view. Press Tab to go into Edit Mode. Backspace the default text and write “Ammo:”. If the text is pixelated in game then fix that the same way we fixed it in the font resolution section of the tutorial. Now duplicate this text and move it to the right next to the first one. Edit this to simply say “0″. This will be our ammo counter that will change every time you pick up an ammo box. Now with that “0″ object still selected, under the properties panel in the Logic Editor window click on “Add Text Game Property”. Change the type to Integer since we’re working with whole numbers, not strings or floats(numbers with decimal places). Now whatever we change this property to will be what’s displayed in the game. We’ll be using logic bricks to change its value shortly.

Let’s switch back to the game level scene now. Go up into the top header and click on the icon to the left of the scene field and choose “Scene” to switch back to our main level scene. Now with the camera selected in this scene go to the logic editor. We’re going to add the HUD as an overlay scene now. So add an Always sensor, connect it to an And controller, then connect that to a Scene actuator. Change the actuator Mode to Add Overlay Scene, and select HUD as the scene.

Now press P in the 3D View to play the game. You should see the HUD scene overlayed on top of the level scene.

Now we’re going to select the ammo box and add some logic to it to send a message to the ammo counter when the main character collides with it. When our ammo counter receives this message it will increase. So select the green ammo box. You’ll notice in the Logic Editor that it already has some logic that makes it spin around and which tells it to delete itself when anything collides with it. Let’s add an actuator that’s connected to that collision sensor. So add a Message actuator. Type in ammo in the Subject field. Connect this to the same controller that the Collision sensor is connected to. Now whenever the main character collides with the ammo box, the ammo box disappears and also sends out the message “ammo”.

Now switch back to the HUD scene and select the ammo counter. Add a Message sensor and type in ammo in the subject field. Connect this to an And controller and connect that to a Property actuator. Change the actuator Mode to Add, change the Property to Text, and change the Value to 1. So this line of logic says that when this receives the message “ammo” that it will add 1 to the Text property.

That should do it. Go back to the game level scene and play the game. Collect the ammo box and notice that the ammo counter changes from 0 to 1. Now duplicate the ammo box all around the scene and collect them all. That does it for changing the text value with logic bricks.

Word Wrapping

If you have a game with long dialogue or storytelling, you’ll want to format your long strings into paragraphs. You can manually start a new line by adding “\n” into your strings in python, or take the manual work out of it by using the textwrap python module. With this module we can take long strings and split them into separate lines at a certain length. Use monospaced font like Courier or DejaVu Sans Mono for best results as line length is determined by the number of characters, not by the line’s pixel width. For example in a regular font like Arial a line with a lot of lower case l’s will not be as long as other lines because the l’s only occupy a tiny amount of space. So to space your lines more consistently, use a monospaced font which is a type of font where every character occupies the same pixel width. For more samples of this check out the wikipedia page Samples of Monospaced Font.

Moving on. In the HUD scene add a new Text object towards the left of the camera view. Again fix the resolution if needed. In the Font properties change the font to a monospaced font like Courier. Back in the Logic Editor add a Text Game Property just like we did before. Keep the Type as String this time. Now create a new text file in the Text Editor and name this “text_wrap”. Paste in the following code:

import textwrap
cont = bge.logic.getCurrentController()
own = cont.owner

startmessage = "Welcome to this tutorial on text in the game engine."

own["Text"] = textwrap.fill(startmessage, 20)

Now add an Always sensor connected to a Python controller that runs the text_wrap script. Press P in the 3D View to see how it looks. The variable startmessage is where we define what the message will say. The variable own["Text"] is how we call the object’s Text property so we can change it. Then we use the function text.wrap.fill(startmessage, 20) to say we want to change the Text property to the startmessage value but split it into lines of 20 characters long. That’s all there is to word wrapping with python!

This message will display on screen once we start the game, but obviously we don’t want to leave it there forever. So add a Delay sensor and change the Delay to 200. Connect this to an And controller and connect that to a Visibility actuator with Visible unchecked. This says that after a delay of 200 tics the object becomes invisible. Now go back to the game level scene and press P in the 3D View to play the game. The start message will pop up, then disappear after a couple seconds. And we’re finished!

Download the finished blend file here

Extra: More Text Formatting

Here’s just a few more basic string formatting options.

capitalize() – Capitalizes the first letter of the string in the parenthesis
lower() – Makes all letters of a string in the parenthesis lowercase
upper() – Makes all letters of a string in the parenthesis uppercase

There are more options for working with strings below:



For more information on learning python you can check out my beginner’s BGE python script tutorial which shows you the basics of using python in the game engine and accessing logic brick information through scripting.

If you have notice any errors or have any comments about the tutorial then please contact me. Until next time!


  • http://Website Falberto

    I have downloaded the demo and it doesn’t work in my Blender 2.71. Am I the only one?

  • http://www.cgmasters.net Chris Plush

    Thanks for catching that, the uploads were incomplete. I just fixed that so the blend files should work now!

  • http://Website Will

    Thanks for this tutorials and the script, this will be useful!
    I was wondering why using a boolean property for the camera?

    • http://www.cgmasters.net Chris Plush

      The cursor needed to be reset to the center initially before the mouselook script did its magic, otherwise if the cursor wasn’t near the center it would make the camera point in a random direction when you first start the game. The easiest way I thought to fix that was by adding a property I could switch on and off. When the property is on, the part of the script that centers the cursor runs then it turns the property off. When the property is off, the mouselook part of the script does its thing.

  • http://Website Neli

    Doesnt work correctly on mine. Usung 2.71 also. My mouse pointer ends up off the screen edge on full screen so it stops looking around.

    • http://www.cgmasters.net Chris Plush

      Ah great catch! Looks like when you’re in full screen it makes it possible to move the cursor fast enough that it moves outside the camera bounds, then it no longer registers mouse movement(which is what triggers the script). I’ve fixed this by adding an always sensor set to true pulse connected to the python script. So the script always runs. Also make sure the camera bounds are within the view when you go into fullscreen. I’ve reuploaded to the same links. Let me know if you spot any more issues, thanks again!

  • http://Website Ксения Халезова

    Its very perfect, i like this, more education – more braingain

  • http://Website Blender Noob

    Very good tutorial. I’d like to ask you something: how could I make a text appear a few seconds when the character hits something (like making appear “ammo acquired” when the player gets some ammo).

    • http://www.cgmasters.net Chris Plush

      Are you familiar with using the Edit Object actuator to add new objects? I would use that, that way you can easily specify how long you want the text to display for before it disappears. If you’re not familiar with adding objects, follow my lead:

      1) In the HUD scene create a new text object that says what you want it to say. Move this to a hidden layer.

      2) In the HUD scene still add an empty in the middle of the camera view.

      3) With the empty selected add a message sensor with ‘ammo’ in the field just like for the ammo count text. Connect that to an And controller and connect that to an Edit Object actuator. By default this actuator is set to Add Object, here’s where we’ll add the text object.

      4) In the object field choose your text object you just made. Set the time to 50 or however long you want it to last. So now when the empty receives message ‘ammo’ it will add the text message in its place for a brief period of time.

      5) Make a note that the text object must be in a hidden layer to be used by the Add Object actuator.

      • Blender Noob

        Thanks for the tips: it works perfectly.

  • Hakimbo

    Nice tutorial…but I’ve noticed that the mouse is inverted. How would one go about changing the controls to regular?

    • http://www.cgmasters.net/ Chris Plush

      You’ve made a powerful enemy by suggesting the other way is regular. Haha, I’ll figure out how to invert it some point soon(probably in the next week) and update the script and blends.

  • Lucky

    Hi, nice tutorial but I have some issues with the mouselook script. I tried to apply it to a scene but the mouse behaves very strange. When I try to look up the camera shakes and now it’s upside down. Don’t know how to fix it. Anybody the same issue?

    • http://www.cgmasters.net/ Chris Plush

      Do the example files work for you or do you get the same problem? And does the system console return any python errors?

      • Lucky

        The example does work. I did edit the cube because I wanted the shape to fit through a door. I noticed that de z rotation was at 180 degree, after putting it back to 0 the strange effect was gone.

  • Jullius

    Pytohon script fail.It won’t work.:(What should I do?

    • http://www.cgmasters.net/ Chris Plush

      What errors show up in the console? Also, the latest blender has a mouselook actuator which makes a lot of this mouselook script obsolete so I’ll be updating this tutorial eventually.

  • Bidibap

    hi, im not good at python (still learning :D ) i want that camera rotation in 90 and -90, but look down not work, can you help me?

    • http://www.cgmasters.net/ Chris Plush

      Do you mean you can get the camera to look up but not down? In the latest version of blender there is actually a new actuator for mouselook so maybe try playing with that instead of scripting the camera movement. To use the actuator, add a “mouse” actuator and choose “look” from the options.

  • Ach Hadda

    Hi there i just want to know why when i click P i can move but the camera don’t fall0w the mouse for some reason ….. thanks

  • Mario Mey

    I think that using text-objects is not stable and undocummented.

    I put 20 text-objects in scene and it takes a lot to enter in BGE. Some of that texts appear Y scaled * 10… very distorted. GameObject.resolution is undocummented in Blender API Documents.

    Thanks for this tutorial, it has several things that will be usefull. But I had no luck with the text.

    Also, there’s BGUI, from Moguri… but I didn’t understand how to use it in my project!

    I continue using texture based text objects.

    • Mario Mey

      Also, it’s important to say that the color of the text-objects is the Object Color, not Material.

      To have in mind!

      • http://www.cgmasters.net/ Chris Plush

        Thanks for the feedback! The section for customizing font already mentions object color to change font color, but I was unaware that so many text objects would slow things down that much. That’s a shame there’s still no reliable and proper text display, but at least this is another option when used in moderation that gives some extra control over its display. Thanks again.

        • Mario Mey

          I apologize about the already-mentioned font color! It was because I didn’t read all the post (my fault).

          Finally I didn’t use this method, also because I wanted to have a white text and a black shadow (duplicated object with black color and moved a little in X and Y), and discovered that the text alpha is not working well with the text behind.

          I really didn’t do benchmark tests with this type of font objects, I had
          only bad performance start-up and alpha artifacts in my file. If some day I do a test, I’ll
          post here.

          Thanks for the fast response!

        • http://www.cgmasters.net/ Chris Plush

          Hmm, these are definitely issues to look into, thanks. I’m actually going to dive into some serious bge research soon for a large scale training course, so this is on my list of things to look into now.

        • KennedyRichard

          Any news on this large scale training?

        • http://www.cgmasters.net/ Chris Plush

          Seems the bge really isn’t going anywhere unfortunately. There is something in development at http://armory3d.org/ for realtime in blender that looks promising though so I’ll keep my eye on that. Otherwise I’ve got my eyes set on learning Unreal after I release the vehicle creation course I’m currently working on(1-2 months). Then you can expect some Unreal tutorials and courses.

        • KennedyRichard

          Thank you for your answer, mr. Plush. Oh, man, as much as it saddens me you have a point. Not sad because of the Unreal tutorial, which is also something for which I’m hyped, but because of BGE.

          While it was long stated that BGE was taking a turn for better in the future, the fact that the pace isn’t picking up much speed makes people just discard it altogether as an option for game development fearing their current in-development games may break whenever the new BGE comes out. And yet, there are even published steam games developed on BGE, even regarding it’s “unfinished” state. Regarding this, may I ask another question? A rather difficult one, sorry. Do you think I should discard the current BGE altogether as an option for developing “professional” (as in marketable) games?

          I’ll also check the armory3d link. Thank you again.

  • Nick Armitt

    I tried this and now the camera falls to the floor and the mouse doesn’t work… Is the fact I am on a mac at college the reason?