BGE Python: Reading and Writing Rotation

Posted by Chris Plush on July 25th, 2014 | Comments (12)


***
Tested as of 2.71. Later versions may need “import bge” added to the top of your scripts.

***

Introduction

This one’s for the Python dabblers that haven’t been able to figure out localOrientation. Using the function localPosition is easy enough because it returns a list of x, y, and z values. Using localOrientation for rotation values, however, returns a 3×3 matrix. So unless you’re brave enough to handle matrices what we’re going to do in this quick tutorial is convert our object’s matrix to degrees for easier reading and changing. For an intro to python scripting in the BGE, check out my beginner’s python tutorial.

Reading Your Object’s Rotation

Open the text editor in Blender and add a new file. Name this “rotation”. Paste in the following code:

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

xyz = own.localOrientation.to_euler()
rotz = math.degrees(xyz[2])
print (rotz)

Now select your object and in the Logic editor add an Always sensor(set to true pulse) and connect it to a Python controller(set to script “rotation”). Add logic bricks for turning the object left and right. Press P over the 3D View and turn the object around a bit so you can see the rotation values change. Then check the system console. It’ll print out the object’s Z rotation value in degrees.

Logic setup:



Z rotation values printed in the console:



This is a simple script. In the first line we import the math module because we’ll need special functions for angle conversions. Then the cont and own lines are standard lines for getting information on the object running the python script(the owner).

The xyz variable is the object’s orientation matrix, except we added to_euler() at the end of it to convert the matrix to radians. Radians are a different angle measurement that ranges from 0 to 2π. So now instead of being a matrix, localOrientation is converted to a list with x, y, and z values in radians. Now we can take each one of these values and convert them into degrees. So the last variable, rotz, takes the third item in the xyz list and converts it to degrees.

Then we print rotz. Now you can see what direction an object is facing. Make a note that the degree values will range from -180 to 180, not 0 to 360(unless you want to add a little extra math to make that happen). Also make a note that to get the x value, it would be xyz[0], and the y value would be xyz[1]. The first item in python lists is 0 in case you were confused.

Setting Your Object’s Rotation

Now reading the rotation value is one thing, but how about changing it? It’s pretty much the same process, except in reverse. Erase your script and paste in the following script:

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

xyz = own.localOrientation.to_euler()
xyz[2] = math.radians(45)
own.localOrientation = xyz.to_matrix()

In this script we still convert localOrientation to euler first. Then we change xyz[2], which is the Z value, to the radian equivalent of 45 degrees(you can put any number or variable you want in there). Then we convert it back to a matrix in the last line and assign it to own.localOrientation. When you press P in the 3D View, the cube will instantly rotate to 45 degrees.

Easy as pi.

Check out a little demo I made of aiming a catapult at a castle. You can even type in your own angles to set the catapult to for precise aiming. There are a couple different short scripts with notes in each one telling you what they do.


Click image for full size

Download the catapult blend file here


-blengine

  • Rudi Ratlos

    I tried to analyse this game, but I wasn´t totally succesful. I couldn´t find out to which object the keyboard sensor for “A” belongs.
    By th way, is there any possibility to get an overview of all used logic bricks and the objects, to which they belong? (Without selecting one object after the other one, in order to see the belonging logic bricks)

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

      The camera owns that “A” keyboard sensor. And yes, you can select all objects together, then their logic bricks should all display in the Logic Editor at the same time. If they don’t, make sure “sel” is enabled at the top of each column of logic bricks to display all selected logic bricks.

      • Rudi Ratlos

        Thank you for the helpful tip!

  • mightyevil

    I’m not sure why, but your rotating script is not doing anything

  • mightyevil

    nevermind

  • rag

    Hi, how do i do the same for bone?
    and how do i select a bone when there are two or more bones. (armature)
    thank you.

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

      I have no idea how to apply this to armature bones in game. For simply selecting bones, go into pose mode(ctrl+tab) and right click on them.

  • LLuistar

    IDK, But for some reason the boulder falls to the ground beneath the catapult once I press [space] to launch. Could it be a problem with my blender version? BTW I’m using the latest version 2.77.

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

      I just tested it on 2.77 and seems to work fine. Are you getting a really slow framerate? That’s the only thing I can think of for the physics being inaccurate. Maybe collision detection is a little different in the latest Blender I’m not sure, I haven’t kept up to date. Also you’ll need to put “import bge” at the tops of all your scripts to get that blend file working right. I noticed the Angle value at the top is showing an error.

  • Joseph Levesque

    Hey, can I use this script in a couple of my public projects? I’m working on a 2d platform game in Blender, and I want to be able to make the player do a 180 when you press the arrow for the opposite direction. This is the best way I could think of. I may or may not be able to give you credit, but if I could use this, it would be greatly appreciated. Thanks!

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

      Yeah absolutely, and no credit necessary but would be great.

      • Joseph Levesque

        Thanks, Chris! I really appreciate it! 😀