Issue Moving Actor and Camera In Same Node

Hi, I just recently started learning Panda 3D and I am trying to have the camera follow the player from an offset.

I learnt how to get the model position for the player and add on to it an offset where the camera will be set, which worked. I also parented the camera to the player which is self.player in my class.

I tried moving the player through a task that would update its position slowly and add on to it, but the camera will not follow the player, though it is the child of self.player.

How can I fix this? Here is my code:

from direct.showbase.ShowBase import ShowBase
from panda3d.core import loadPrcFileData
from panda3d.core import NodePath
from direct.actor.Actor import Actor
from direct.task import Task
from panda3d.core import LPoint3f

# Config Variables
winTitle = "Max's Panda 3D Program"
iconPath = "pandaIcon.ico"
fov = 50
frameMeter = True
winWidth = 720
winLength = 1280
fullscreen = False
red = 135
green = 168  # RGB Values
blue = 222

red = red / 255
green = green / 255  # Convert to background-color doubles
blue = blue / 255

gameConfiguration = f"""
win-size {winLength} {winWidth}
window-title {winTitle}
show-frame-rate-meter {frameMeter}
background-color {red} {green} {blue} 0
default-fov {fov}
fullscreen {fullscreen}
icon-filename {iconPath}
"""

loadPrcFileData("", gameConfiguration)


class Main(ShowBase): # Class created, inherits ShowBase.
    def __init__(self):
        ShowBase.__init__(self) # Initialize ShowBase.
        self.disable_mouse()  # Disables default Panda camera controls.

        environmentNode = NodePath("Environment") # Creates Panda Node in scene graph.

        scene = self.loader.loadModel("phase_8/models/neighborhoods/the_burrrgh.bam")
        skybox = self.loader.loadModel("phase_3.5/models/props/TT_sky.bam")

        scene.reparentTo(environmentNode)  # Parents scene inside 'Environment' node.
        skybox.reparentTo(environmentNode)
        environmentNode.reparentTo(self.render) # Reparents node and children to 'render' (Scene Graph root).

        self.player = Actor("phase_6/models/char/dale_1000.bam",
                            {"idleAnim":"phase_6/models/char/dale_idle.bam",
                             "walkAnim":"phase_6/models/char/dale_walk.bam"})
        self.player.setScale(3.5)
        self.player.reparentTo(self.render)
        self.player.loop("idleAnim")

        self.task_mgr.add(self.updateCamTask, "UpdateCameraTask")
        self.task_mgr.add(self.move, "MovePlayer")

    def updateCamTask(self, task):
        self.camera.reparentTo(self.player)
        self.camera.setPos(self.player.get_pos() + LPoint3f(0, -4.5, 2))
        self.camera.setHpr(0, -5, 0)
        return Task.cont

    def move(self, task):
        self.player.setPos(self.player.get_pos() + LPoint3f(.005, 0, 0))
        return Task.cont

game = Main()
game.run()

You only need to parent the camera to the player node and set its offset once. From that point on, the camera will inherit the transform of the player. So move everything from the updateCamTask to your init and it should work

Edit: fixed a typo

1 Like

Oh that makes sense, let me try that. Ill get back to you if it works.

Looks like it works! Thanks for the help!

1 Like

Glad to have been of help. Best of luck with your project!