Third Person Camera Issues with Bullet

So I have to believe that somewhere there is a post about this. And it seems like it should be incredibly simple. But alas this has stumped both my web search ability and my coding ability for almost a week now so I figure I might as well ask for help.

I’m attempting to create a relatively simple Third person Camera. Left mouse button allows for the player to move the camera around the character. Right mouse button allows the player to move the player with the mouse itself. This works fine. The issue is that when I have the camera get stopped by the terrain and the player keeps attempting to move the mouse the camera will slowly move towards to the character. I believe the reason for this is that the Z is moved to above the ground but the X and Y are still changing to try to move under the character. The relevant code is as follows:

__author__ = 'jonyfries'

from direct.showbase.DirectObject import DirectObject
from panda3d.core import Vec3, WindowProperties


class GameCamera(DirectObject):
    def __init__(self, target, offset, position, world):
        base.disableMouse()

        # setup target
        self.target = target
        self.cameraTarget = target.attachNewNode("CameraTargetNode")
        self.cameraTarget.setPos(offset)

        # setup camera
        self.cameraBase = self.cameraTarget.attachNewNode("CameraBaseNode")
        self.cameraBase.setPos(position)
        camera.reparentTo(self.cameraBase)
        self.rotationSpeed = 2880
        self.zoomSpeed = 5

        # setup misc
        self.world = world

        # setup Tasks
        self.addTask(self.updateCamera, "UpdateCamera", priority=10)

    def setMouseHidden(self, hidden):
        props = WindowProperties()
        props.setCursorHidden(hidden)
        base.win.requestProperties(props)

    def enableRPGMouseControl(self):
        self.ignoreAll()
        self.accept("mouse1", self.addTask, [self.startRotateCamera, "StartRotateCamera"])
        self.accept("mouse1-up", self.endMouseLook)
        self.accept("mouse3", self.addTask, [self.startMouseLook, "StartMouseLook"])
        self.accept("mouse3-up", self.endMouseLook)
        self.accept("wheel_up", self.zoom, [-self.zoomSpeed])
        self.accept("wheel_down", self.zoom, [self.zoomSpeed])

    def zoom(self, zoomDirection):
        self.cameraBase.setPos(self.cameraBase.getPos() + Vec3(0, zoomDirection, 0))
        if self.cameraBase.getY() < 20:
            self.cameraBase.setY(20)

    def endMouseLook(self):
        self.setMouseHidden(False)

        self.removeTask("StartMouseLook")
        self.removeTask("MouseLook")
        self.removeTask("StartRotateCamera")
        self.removeTask("RotateCamera")

    def enableTPSMouseControl(self):
        self.ignoreAll()
        self.addTask(self.startMouseLook, "startMouseLook")

    def disableMouseControl(self):
        self.ignoreAll()

    # Tasks
    def updateCamera(self, task):
        pFrom = self.cameraBase.getPos(render)
        pTo = self.cameraBase.getPos(render) + Vec3(0, 0, -2.99999)
        rayCastResult = self.world.rayTestClosest(pFrom, pTo)

        if rayCastResult.hasHit():
            self.cameraBase.setZ(render, rayCastResult.getHitPos().z + 3.0)
        self.cameraBase.setHpr(render, Vec3(-180, 0, 0))

        camera.lookAt(self.cameraTarget)

        return task.cont

    def startRotateCamera(self, task):
        print self.cameraBase.getPos()
        if base.mouseWatcherNode.hasMouse():
            self.setMouseHidden(True)

            self.screenCenter = (base.win.getXSize() / 2, base.win.getYSize() / 2)
            base.win.movePointer(0, self.screenCenter[0], self.screenCenter[1])
            self.firstMouseLook = True
            self.addTask(self.rotateCamera, "RotateCamera", priority=9)
            return task.done
        else:
            return task.cont

    def rotateCamera(self, task):
        if not base.mouseWatcherNode.hasMouse():
            self.addTask(self.startRotateCamera, "StartRotateCamera")
            return task.done

        if not self.firstMouseLook:
            deltaRotation = self.rotationSpeed * globalClock.getDt()

            rotationH = -base.mouseWatcherNode.getMouseX() * deltaRotation
            self.cameraTarget.setH(self.cameraTarget.getH() + rotationH)

            rotationP = -base.mouseWatcherNode.getMouseY() * deltaRotation
            self.cameraTarget.setP(self.cameraTarget.getP() + rotationP)
        else:
            self.firstMouseLook = False

        base.win.movePointer(0, self.screenCenter[0], self.screenCenter[1])
        return task.cont

    def startMouseLook(self, task):
        if base.mouseWatcherNode.hasMouse():
            self.setMouseHidden(True)

            self.target.setH(self.cameraTarget.getH() + self.target.getH())
            self.cameraTarget.setH(0)

            self.screenCenter = (base.win.getXSize() / 2, base.win.getYSize() / 2)
            base.win.movePointer(0, self.screenCenter[0], self.screenCenter[1])
            self.firstMouseLook = True
            self.addTask(self.mouseLook, "MouseLook", priority=9)
            return task.done
        else:
            return task.cont

    def mouseLook(self, task):
        if not base.mouseWatcherNode.hasMouse():
            self.addTask(self.startMouseLook, "StartMouseLook")
            return task.done

        if not self.firstMouseLook:
            deltaRotation = self.rotationSpeed * globalClock.getDt()

            rotationH = -base.mouseWatcherNode.getMouseX() * deltaRotation * 250
            self.target.setAngularMovement(rotationH)

            rotationP = -base.mouseWatcherNode.getMouseY() * deltaRotation
            self.cameraTarget.setP(self.cameraTarget.getP() + rotationP)
        else:
            self.firstMouseLook = False

        base.win.movePointer(0, self.screenCenter[0], self.screenCenter[1])
        return task.cont

Some one must have made a third person camera with bullet before and had issues (either that or I’m going to feel really stupid :slight_smile: ). So if you can point me in the right direction that would be great! Thanks!