I’m having a little bit of trouble with the WorlPosition command.
I want save position by pressing a key and then put the object back to the position by pressing another key. But the obj.worldPosition = pos doesn’t work.
Here’s my code
import GameLogic
# get the controller
controller = GameLogic.getCurrentController()
senlist = controller.sensors
obj = controller.owner
on = senlist["On"]
off = senlist["Off"]
coll = senlist["Collision"]
touche = senlist["Touche"]
reg = senlist["reg"]
actlist = controller.actuators
spin = actlist["Spin"]
make = actlist["Make"]
if on.positive == True:
controller.activate(spin)
if off.positive == True:
controller.deactivate(spin)
if reg.positive == True:
pos = obj.worldPosition
if touche.positive == True:
obj.worldPosition = pos
if I put obj.worldPosition = [ 1.0, 1.0, 2.0] then it workds, but with the variable it doesn’t I don’t understand how to put it.
Also, is there a way of displaying the content of a variable? I’ve tried print(pos) but nothing happens. I don’t know where to look.
Some debug print is mandatory at this point.
Print outputs should be visible on system console (help menu: ‘Toggle System Console’).
Are you using blender 2.62?
…so, make the console visible and print(pos), according to your original idea.
Also, you should ensure that your code is activated at every frame, not only once. For example, if you use an always sensor connected to your python controller, at least one trigger button (three small dots: …) should be activated.
This is a potential error situation. You create a variable when one condition is met. You use this variable when another (independent) condition is met.
There is no guaranty that both conditions are true at the same time.
If the second condition is met but not the first one you will get an error (see console).
better do this:
if reg.positive:
pos = obj.worldPosition
if touche.positive:
obj.worldPosition = pos
Design issue
Finally this makes no sense at all as it sets what it just read (obj.worldPosition=obj.worldPosition).
The variable “pos” will not survive the end of the script.
Suggestion
I think you need to implement what mb10 suggested:
if reg.positive:
obj["storedPosition"] = obj.worldPosition.copy()
if touche.positive:
obj.worldPosition = obj["storedPosition"]
Do not forget the copy() attribute.
Reason: worldPosition returns a reference to the position of the object. That means if the position changed the value of the reference changed too as it is a reference to exactly the same data.
You are interested in the value at the time of storage not the value at the time of restore. So create a independent copy of the position with the copy() attribute.
Remarks: Code design
I suggest to use module mode. Then implement two different access points. One to store the position and one to restore the position. This helps to keep your logic/code simple and well structured. Mixing independent code together is usually not a good idea.
e.g
MyModule.storePosition
MyModule.restorePosition
Comparing boolean values with a boolean constant.
if booleanValue == True:
“if” expects a boolean value.
KX_Sensor.positive provides a boolean value already. You do not ned to compare it against a boolean constant. It simple eats more processing time. Better use the value directly.
if booleanValue:
Reason:
“booleanValue == True” is logically the same as “booleanValue”.
(in opposite to:
“booleanValue == False” is logically the same as “not booleanValue”.
So, I’ve tried with the mathutils but it doesn’t work either. As for my sensors I use keyboard sensors. But I’m not sure how I can make sure the code is activated at every frame.
I suspected that your code run only once, but this is not the case: if you are using keyboard sensors the script is triggered at every keypress, and this should be OK.
Can you see the console now?
Did you print object position on it?
You should see a new print at every keypress. Do you?
Despite I suggested this solution as an alternative, I’m afraid it is not feasible, because it is not possible to assign a vector to an object property: object properties, in fact, are scalars.
So I followed all your advice, and it still doesn’t work. I made progress though. I know where the problem is now. The debug console gives me the position so I see where things don’t do what they’re supposed to.
I made a function state_record, and at first I could not get the vector out, even though I put return and then insert the function into a variable. The result was NULL.
Finnally I can get the vector out of the fonction with the GameLogic variable. But now I have another issue I can’t fix. I watched the debug console and apparently when the “touche.position” becomes true, the position is taken again and therefore no movement is done. I tried to cheat by using other variables, x,y,z but in vain, they change as well.
I’m not sure what to do next.
Here’s my code for now, it’s not too clean for now, I’ve tried a lot of things.
def state_record():
if reg.positive:
pos = obj.worldPosition
bod = pos.copy()
print(bod)
GameLogic.pose = pos
state_record()
x = GameLogic.pose[0]
y = GameLogic.pose[1]
z = GameLogic.pose[2]
I also suggest to implement what mb10 mentioned - a check to see if a key is pressed, and if so, store the value (the object’s world position) in the object (which is fine to do; object properties set in Blender (not with Python) can only be one of the predefined variable types). Then, in the other key check, restore the position to the object. It’s pretty simple:
from bge import logic
cont = logic.getCurrentController() # Controller running this script
obj = cont.owner
savekey = cont.sensors['Savekey'] # Sensor for saving the object's position; named 'Savekey' here - you can rename it what your keyboard sensor is
loadkey = cont.sensors['Loadkey'] # Sensor for loading the object's position
if not 'init' in obj: # Initialize variables
obj['init'] = 1
obj['lastpos'] = obj.worldPosition.copy() # Just set the object's last position variable a copy of the world position Vector
if savekey.positive:
obj['lastpos'] = obj.worldPosition.copy()
if loadkey.positive:
obj.worldPosition = obj['lastpos']
That should do it.
EDIT: You probably need to make sure the keyboard sensors are set to TAP to only run once, not all of the time that they’re held down. Also, you probably couldn’t get the vector out of the function because you didn’t use ‘return variable’, where ‘variable’ is the vector that you get. Just ‘return’ won’t do anything.
i never used the “global dictionary” (GlobalLogic), but i tried and work as excpected
in your script there a error
def state_record():
if reg.positive:
pos = obj.worldPosition
bod = pos.copy()
print(bod)
GameLogic.pose = pos #<<<<<<<<<
state_record()
GameLogic.pose = pos
save only the reference of worldPosition!!
you need to save instead “bod”
but i counsill to not create ton of variable which make confusion.
in this way:
def state_record():
if reg.positive:
GameLogic.pose = obj.worldPosition.copy()
print(GameLogic.pose)
state_record()
or if want keep the same code:
def state_record():
if reg.positive:
pos = obj.worldPosition
bod = pos.copy()
print(bod)
GameLogic.pose = bod
state_record()
if not 'init' in obj: # Initialize variables
obj['init'] = 1
obj['lastpos'] = obj.worldPosition.copy() # Just set the object's last position variable a copy of the world position Vecto
this provvide to avoid this potential error
for this,I prefer keep the script which run ever…(laziness )