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 ). So if you can point me in the right direction that would be great! Thanks!