Script help and decision

So I’m having a bit of a problem understanding why my player panda is acting the way it is. What I want to do is offset the camera from my playerDummyNode so that it sits above the dummy node by 5 units. However, no matter what I do, it seems to not accept this. What I thought happened when you reparentTo(‘parent’) that the PandaNode now exists on a coordinate system based on the parent node. Is this not true? Also, keep in my I’m fairly new to Panda3d so please don’t kill, destroy, crush, swag my code too badly (although constructive criticism is always welcomed!)

import sys
from math import *
from pandac.PandaModules import loadPrcFileData
loadPrcFileData('', 'win-size 1024 768')
from direct.task import Task
from direct.actor.Actor import Actor
from pandac.PandaModules import *
from direct.showbase.ShowBase import ShowBase
from panda3d.core import WindowProperties

class Main(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        base.setBackgroundColor(0,0,0)
        #setup key map
        self.newKeyMap = keyMapper()
        print self.newKeyMap.keyMap
        
        #setup level
        self.newEnvironemnt = Environment()
        
        #setup player
        self.newPlayer = Player()
        self.newPlayer.playerActor.setPos(0,0,0)
        #base.camera.reparentTo(self.newPlayer.playerDummyNode)
        self.newPlayer.playerActor.setPos(base.camera.getX(),base.camera.getY(),base.camera.getZ())
        
        #setup character movement
        base.accept("escape", sys.exit)
        base.accept("mouse1", self.printMe)
        base.accept("mouse2", self.printMe)
        
        #player movement w a s d format
        base.accept("w", self.newKeyMap.setKey, ["w", True]) #move forward
        base.accept("s", self.newKeyMap.setKey, ["s", True]) #move backward
        base.accept("a", self.newKeyMap.setKey, ["a", True]) #strafe left
        base.accept("d", self.newKeyMap.setKey, ["d", True]) #strafe right
        base.accept("w-up", self.newKeyMap.setKey, ["w", False]) #stop forward
        base.accept("s-up", self.newKeyMap.setKey, ["s", False]) #stop backward
        base.accept("a-up", self.newKeyMap.setKey, ["a", False]) #stop strafe left
        base.accept("d-up", self.newKeyMap.setKey, ["d", False]) #stop strafe right
        #base.accept("w-down", PlayerMovement.moveForward)
        
        
        
        #set a task manager
        self.setupTaskMgr()
    def printMe(self):
        print "mouse clicked"
    
    def playerMovement(self, task):
        '''
        all movement except 'heading' (controlled by player camera) will be included here
        '''
        dt = globalClock.getDt()
        if(dt > .20):
            return Task.cont
        
        if(self.newKeyMap.keyMap["w"] == True):
            self.newPlayer.playerDummyNode.setY(self.newPlayer.playerDummyNode, 15 * dt)
            #self.newPlayer.playerActor.setPos(self.newPlayer.playerDummyNode.getX(), self.newPlayer.playerDummyNode.getY(), self.newPlayer.playerDummyNode.getZ()-10)
            
            '''
            base.camera.setY(base.camera, 15 * dt)
            self.newPlayer.playerActor.setPos(base.camera.getPos())'''
            print self.newPlayer.playerActor.getPos()
        
        if(self.newKeyMap.keyMap["s"] == True):
            self.newPlayer.playerDummyNode.setY(self.newPlayer.playerDummyNode, -15 * dt)
            #self.newPlayer.playerActor.setPos(self.newPlayer.playerDummyNode.getPos())
            
        return Task.cont
    def setupTaskMgr(self):
        #setup initial tasks and add them to task manager
        self.taskMgr.add(self.movePointer, "PlayerCamera")
        self.taskMgr.add(self.playerMovement, "PlayerControl")
        

    def movePointer(self, task):
        md = base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        
        if base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2):
            #base.camera.setP(base.camera.getP() - (y - base.win.getYSize()/2) * .1)
            self.newPlayer.playerDummyNode.setP(self.newPlayer.playerDummyNode.getP() - (y - base.win.getYSize()/2) * .1)
            #ensure that the camera can't go over 90 degrees and do a 360 turn which is impossible
            '''
            if base.camera.getP() > 90:
                base.camera.setP(90)
            if base.camera.getP() < -90:
                base.camera.setP(-90)'''
            if self.newPlayer.playerDummyNode.getP() > 90:
                self.newPlayer.playerDummyNode.setP(90)
            if self.newPlayer.playerDummyNode.getP() < -90:
                self.newPlayer.playerDummyNode.setP(-90)
            #base.camera.setH(base.camera.getH() - (x - base.win.getXSize()/2) * .1)
            self.newPlayer.playerDummyNode.setH(self.newPlayer.playerDummyNode.getH() - (x - base.win.getXSize()/2) * .1)
            #self.newPlayer.playerDummyNode.setH(base.camera.getH())
        return Task.cont
        
class Player(Main):
    def __init__(self):
        self.playerDummyNode = render.attachNewNode("PlayerDummyNode")
        self.setupCameraBehavior()
        self.setupPlayerModel()
        self.playerAttributes(15, 100)
    def setupCameraBehavior(self):
        base.disableMouse()
        self.props = WindowProperties(base.win.getProperties())
        self.props.setCursorHidden(True)
        self.props.setFullscreen(True)
        self.props.setMouseMode(WindowProperties.MAbsolute)
        base.win.requestProperties(self.props)
        base.camera.reparentTo(self.playerDummyNode)
    def setupPlayerModel(self):
        #setup player and load model
        
        self.playerActor = Actor("models/panda-model", {"walk": "models/panda-walk4"})
        self.playerActor.setScale(0.03, 0.03, 0.03)
        self.playerActor.reparentTo(self.playerDummyNode)
        #self.playerActor.setHpr(-180,0,0)
    def playerAttributes(self, runSpeed, health):
        self.runSpeed = runSpeed
        self.health = health
    
            
class Environment():
    def __init__(self):
        #load environment and setup to render
        self.landEnv = loader.loadModel("models/environment")
        self.landEnv.setPos(-8, 42, 0)
        self.landEnv.setScale(0.25, 0.25, 0.25)
        self.landEnv.reparentTo(render)
        
class keyMapper():
    def __init__(self):
        self.keyMap = {"w" : False, 
                       "s" : False,
                       "a" : False,
                       "d" : False}
        
    def setKey(self, key, value):
        self.keyMap[key] = value
        
        #diagnostics
        #print key, value
        
    
app = Main()
app.run()

Okay so I feel like a dunce…I took a break from my code and had some coffee and figured out some things…

class Main(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        base.setBackgroundColor(0,0,0)
        #setup key map
        self.newKeyMap = keyMapper()
        print self.newKeyMap.keyMap
        
        #setup level
        self.newEnvironemnt = Environment()
        
        #setup player
        self.newPlayer = Player()
        #base.camera.reparentTo(self.newPlayer.playerDummyNode)
        
        #Player offset to the playerDummyNode
        self.newPlayer.playerActor.setPos(self.newPlayer.playerDummyNode.getX(),self.newPlayer.playerDummyNode.getY()-10,self.newPlayer.playerDummyNode.getZ())
        
        #Camera offset to the playerDummyNode
        base.camera.setPos(self.newPlayer.playerDummyNode.getX(),self.newPlayer.playerDummyNode.getY(),self.newPlayer.playerDummyNode.getZ()+10)
        
        #setup character movement
        base.accept("escape", sys.exit)
        base.accept("mouse1", self.printMe)
        base.accept("mouse2", self.printMe)
        
        #player movement w a s d format
        base.accept("w", self.newKeyMap.setKey, ["w", True]) #move forward
        base.accept("s", self.newKeyMap.setKey, ["s", True]) #move backward
        base.accept("a", self.newKeyMap.setKey, ["a", True]) #strafe left
        base.accept("d", self.newKeyMap.setKey, ["d", True]) #strafe right
        base.accept("w-up", self.newKeyMap.setKey, ["w", False]) #stop forward
        base.accept("s-up", self.newKeyMap.setKey, ["s", False]) #stop backward
        base.accept("a-up", self.newKeyMap.setKey, ["a", False]) #stop strafe left
        base.accept("d-up", self.newKeyMap.setKey, ["d", False]) #stop strafe right
        #base.accept("w-down", PlayerMovement.moveForward)
        
        
        
        #set a task manager
        self.setupTaskMgr()
    def printMe(self):
        print "mouse clicked"
    
    def playerMovement(self, task):
        '''
        all movement except 'heading' (controlled by player camera) will be included here
        '''
        dt = globalClock.getDt()
        if(dt > .20):
            return Task.cont
        
        if(self.newKeyMap.keyMap["w"] == True):
            self.newPlayer.playerDummyNode.setY(self.newPlayer.playerDummyNode, 15 * dt)
            #self.newPlayer.playerActor.setPos(self.newPlayer.playerDummyNode.getX(), self.newPlayer.playerDummyNode.getY(), self.newPlayer.playerDummyNode.getZ()-10)
            
            '''
            base.camera.setY(base.camera, 15 * dt)
            self.newPlayer.playerActor.setPos(base.camera.getPos())'''
            print self.newPlayer.playerActor.getPos()
        
        if(self.newKeyMap.keyMap["s"] == True):
            self.newPlayer.playerDummyNode.setY(self.newPlayer.playerDummyNode, -15 * dt)
            #self.newPlayer.playerActor.setPos(self.newPlayer.playerDummyNode.getPos())
            
        return Task.cont
    def setupTaskMgr(self):
        #setup initial tasks and add them to task manager
        self.taskMgr.add(self.movePointer, "PlayerCamera")
        self.taskMgr.add(self.playerMovement, "PlayerControl")
        

    def movePointer(self, task):
        md = base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        
        if base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2):
            #base.camera.setP(base.camera.getP() - (y - base.win.getYSize()/2) * .1)
            self.newPlayer.playerDummyNode.setP(self.newPlayer.playerDummyNode.getP() - (y - base.win.getYSize()/2) * .1)
            #ensure that the camera can't go over 90 degrees and do a 360 turn which is impossible
            '''
            if base.camera.getP() > 90:
                base.camera.setP(90)
            if base.camera.getP() < -90:
                base.camera.setP(-90)'''
            if self.newPlayer.playerDummyNode.getP() > 90:
                self.newPlayer.playerDummyNode.setP(90)
            if self.newPlayer.playerDummyNode.getP() < -90:
                self.newPlayer.playerDummyNode.setP(-90)
            #base.camera.setH(base.camera.getH() - (x - base.win.getXSize()/2) * .1)
            self.newPlayer.playerDummyNode.setH(self.newPlayer.playerDummyNode.getH() - (x - base.win.getXSize()/2) * .1)
            #self.newPlayer.playerDummyNode.setH(base.camera.getH())
        return Task.cont

That’s my new Main() with the fixed offsets

What I did:

  1. figured out I was setting my playerActor’s position to the camera’s position NOT the playerDummyNode’s position
self.newPlayer.playerActor.setPos(base.camera.getX(),base.camera.getY(),base.camera.getZ()

So I removed this and then figured out this

#Player offset to the playerDummyNode
        self.newPlayer.playerActor.setPos(self.newPlayer.playerDummyNode.getX(),self.newPlayer.playerDummyNode.getY()-10,self.newPlayer.playerDummyNode.getZ())
        
        #Camera offset to the playerDummyNode
        base.camera.setPos(self.newPlayer.playerDummyNode.getX(),self.newPlayer.playerDummyNode.getY(),self.newPlayer.playerDummyNode.getZ()+10)

This may not be a big deal for some but for starting out people, it’s awesome to figure out what went wrong with your code! Anyway, I hope this helps anyone who is confused (as I was) about reparentTo()