Parent + get/setPosition problem

Hi

I have this small problem. I have a camera and in front of the camera stands a cube. When I move the camera (left or right) the cube needs to move the same. So I made the cube a child of the Camera. Then when I press X I can’t control the camera anymore but only the cube. After I am done with moving the cube I press Z and the cube needs to be back in front of the cube where it first used to be.

The problem is that the cube doesn’t go back to the same spot again.

Example: When I press left (camera & Cube go left)
When I print out the values I get the Initial Position of the cube [x,y,z] for example [-1.33, -5.57, 2.42]
Then I press X to move the cube and move it to the left. Press Z to place the cube back to it’s original position. Print out the Initial Position (so I can see that nothing has changed all of a sudden: [-1.33, -5.57, 2.42] (So it’s still the same)
Then I print out his actual position: [-3.39, -5.62, 2.42]

For the file see: http://www.sceneupload.com/file/3387/Parent-Problem-rar.html

Can anyone help me get the cube back to his original position in front of the cam again?

The problem doesn’t occur when I unparrent the cube and the camera. Only I need the cube in front of the camera when I move the camera, so the cube is a child of the camera.

Your link takes to some non-english website and there no download buttons.
Okay - i got it - i have to enter the code. okayi have downloaded

Cheer ! Solved your problem
If you use get/set parent i think the error will come. So use IPO to store the inital pos of the cube. And play the ipo (Frame 2 to 1) when you press Z. Don’t store the pos and set it again. Remove those things.
Do the following :
(While in Frame 1) Select the Cube and Press I. Click Loc and Create a Loc IPO that stores the intial pos.
Now add a IPO actuator – Play 2 to 1
In the Python script change the following code “Placemode”: At the end
if gotowalkmode==1…:
g.walkmode = 1
act = cont.getActuator(“act”)
GameLogic.addActiveActuator(act,1)

There’s a bug with Parent + get/setPosition. But there is a fairly easy work around.

The bug: Move the parent and new position of the parent isn’t passed to getPosition. But it is passed to setPosition.

In other words, parent and child are parented one unit apart. Don’t move the parent and get/setPosition works perfectly. Move the parent and child five units (they are still one unit apart). child.getPosition() gets the distance from the original position of the parent which is 6 units. Then when you use child.setPosition() it places the child 6 units from the new position of parent instead of the one unit.

The solution is to get the distance the parent moved and subtract it from the child.getPosition(). A pain but it works like a charm. 6 lines of code and your blend was working fine.

Hi Knordy,

Can you put together a much simpler example of the bug in a .blend ( eg maybe just using two boxes, one parented, a simple script, and maybe just one scene ).

This will allow us to focus just on the particular problem ( there will be less non-related noise ).

Many thanks…
Mal

Sorry. I should have included the code. Here it is.

####       PlaceMode.py


# Attached to cube.001, scene, layer 1

g = GameLogic
cont = g.getCurrentController()
own =  cont.getOwner()

left = cont.getSensor("left")
right = cont.getSensor("right")

gotoWalkMode = cont.getSensor("WalkMode")

moveLR = cont.getActuator("moveEmptyLR")
#moveRight = cont.getActuator("moveRight")

###########################################$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

########  NEW CODE TO FIX BUG

#Camera is parent so...
# get camera
cam = GameLogic.getCurrentScene().active_camera

# get the parent start position
if hasattr(GameLogic, 'getParentStart') == False:
    GameLogic.getParentStart = cam.getPosition()

# get camera position
posCam = cam.getPosition()

#########################################################################

if g.getMyPosition == 1:
    g.myInitialPosition = own.getPosition()
    g.getMyPosition = 0
    print "Cube Initial Position = ", g.myInitialPosition

if g.walkMode == 0:
    if left.isPositive():
        moveLR.setDLoc(-0.02,0.0,0.0,1)
        g.addActiveActuator(moveLR,1)
    elif right.isPositive():
        moveLR.setDLoc(0.02,0.0,0.0,1)
        g.addActiveActuator(moveLR,1)
    else:
        moveLR.setDLoc(0.0,0.0,0.0,1)
        g.addActiveActuator(moveLR,1)
        
if gotoWalkMode.isPositive() and g.oneClick == 0:
    g.walkMode = 1

    ###############################################
    
    ###       NEW CODE TO FIX BUG
    
    # just to make it easier to type
    camStart = GameLogic.getParentStart
    posCube = g.myInitialPosition
    
    # Distance Parent moved after being parented
    camMoved = ([(posCam[0] - camStart[0]), (posCam[1] - camStart[1]), (posCam[2] - camStart[2])])
    
    # fixed position
    fixedPosition = ([(posCube[0] - camMoved[0]), (posCube[1] - camMoved[1]), (posCube[2] - camMoved[2])])
    
        
    #own.setPosition(g.myInitialPosition)
    own.setPosition(fixedPosition)

    ######################################################

    print "Cube back to Initial Position = ", g.myInitialPosition
    print "Cubes actual position = ", own.getPosition()
    g.oneClick = 1

Vimal & cthames, thank you both. I tried both solutions and both worked :slight_smile: Thank you both a lot :slight_smile:

Bug reported here:

https://projects.blender.org/tracker/index.php?func=detail&aid=17549&group_id=9&atid=125