problem using WorlOrientation for defining limits

Hi everyone,
I’m trying to make a script that will stop the object from rotating when it reaches 90° and -90° on the X axis.
I’ve used the WorldOrientation method to do it. But it generates me a 3x3 Matrix. I wasn’t too sure how to use it so I converted it to Euler with to_euler() which makes more sense to me. After some tests I’ve determined that for my object to be inside the ±/90° limit it needs to be inside between -3.1300 and -0.0440.
So I made an if condition so that the object can only rotate up and down, well down not yet, but only up when it meets the prior condition. When it does then I activate a rotation with an actuators already set to rotate the object the way I need.
The problem is that when it starts moving it doesn’t stop. The whole purpose of my script was to stop the object from moving 360°. I want to make it stop when it goes beyond it’s limit. I’ve tried a while with the condition that the key is pressed, but then Blender crashed, so I’m not too sure what to do now.

Here’s my code so far.

    
from bge import logic
import mathutils
from mathutils import Matrix

cont = logic.getCurrentController()
obj = cont.owner
keyup = cont.sensors['KeyUp'] 
keydown = cont.sensors['KeyDown']
rotup = cont.actuators['RotUp']

if keyup.positive:
     print(obj.worldOrientation.to_euler())
     bob = obj.worldOrientation.to_euler()
     print(bob[1])
     if bob[0] < -0.0440 and bob[0] > -3.1300:
         while keyup.positive:
             cont.activate(rotup)
     

Thank you in advance for your help.

You need to deactivate the actuator when it is not moving.
Also, if you want to limit the rotation, it may help to get the degrees.
Lastly, you shouldn’t use a while loop in the game engine - it won’t work in your case, because the keyboard status won’t change within a frame.
revised code:


from math import degrees
from bge import logic
from mathutils import Matrix

cont = logic.getCurrentController()
obj = cont.owner
keyup = cont.sensors['KeyUp'] 
keydown = cont.sensors['KeyDown']
rotup = cont.actuators['RotUp']

if keyup.positive:
	radians_rotation = obj.worldOrientation.to_euler()
	x, y, z = [degrees(v) for v in radians_rotation]
	if (x > - 90) and (x < 90):
		cont.activate(rotup)
	else:
		cont.deactivate(rotup)
else:
	cont.deactivate(rotup)

thank you agoose77, your script works but not exactly how I need it to. If I keep pressing the key it keeps moving 360°. I want it to stop when it goes beyond its limits even if the key is still pressed.

It actually does work, but the setup is specific:
Rotation_Example.blend (650 KB)

Okay now it works I’ve added the always sensor and checked the "’ box but I don’t understand why it works now. Thank you very much though, you’ve helped me a lot.

Basically, before the script only executed for one frame even if you held the keyboard. You could just enable the ‘…’ button, or use an always sensor that does that for you. That way, it continutes to check the rotation, and if it is above 90 it stops the actuator.

Okay I didn’t know it, I’ll keep that in mind for future scripts. Thanks a lot for your help.

Hmm, that is very interesting, so, how do you do the opposite? Turn degrees into 3X3 Matrix, or how do you just set the orientation from degree?

Most mathutils classes have a to_alternative attribute

mathutils.Euler.to_matrix()
mathutils.Matrix.to_euler()
mathutils.Euler.to_quaternion()

and so on.

Direct orientation assignment is also supported:

# phi, tet, psi are euler angles in radians
object.worldOrientation = [phi, tet, psi] # set orientation with respect to the <b>world</b>
object.localOrientation = [phi, tet, psi] # set orientation with respect to <b>parent</b> object