# 3rd person control relative to camera - speed problem

Hey guys, I’m having trouble defining an equal moving speed (i.e. a vector) for every direction, when the first goal was to make my input translate into Ralph moving to the desire position on screen. I eventually made him behave accordingly, which means that if I press Left, I make Ralph change his position to the Left relatively to the camera (no matter if he animates running backwards, for example). The problem is: the speed is different from when I run to the sides to when I run forward or forward and to the sides. I think that has something to do with getting a newVector that is relative to the camera and applying it to Ralph, because when I print it, it gives 5 and -5 on the X axis, and less on the Y axis.

``````def move(self, task):

# If the camera-left key is pressed, move camera left.
# If the camera-right key is pressed, move camera right.
base.camera.lookAt(self.ralph)
if (self.keyMap["cam-left"] != 0):
base.camera.setX(base.camera, - 15 * globalClock.getDt())
if (self.keyMap["cam-right"] != 0):
base.camera.setX(base.camera, + 15 * globalClock.getDt())

startpos = self.ralph.getPos()
self.moveVector = Vec3(0, 0, 0)

if (self.keyMap["left"] != 0):
self.moveVector.setX(-1)
if (self.keyMap["right"] != 0):
self.moveVector.setX(1)
if (self.keyMap["forward"] != 0):
self.moveVector.setY(1)
if (self.keyMap["backward"] != 0):
self.moveVector.setY(-1)

if self.moveVector.length() > 1:
self.moveVector.normalize()
self.newVector = self.ralph.getRelativeVector(base.camera, self.moveVector)
self.newVector.setZ(0)
self.ralph.setPos(self.ralph.getX() + self.newVector.getX() * globalClock.getDt(),
self.ralph.getY() + self.newVector.getY() * globalClock.getDt(), self.newVector.getZ())``````

Tell me if I need to change the code, but I want to keep the design of Arrow keys making the character run, while A and S make the camera rotate to the sides. I still need to make Ralph face the new direction, but that’s something else.

EDIT:

``````if (self.keyMap["left"] != 0):
self.moveVector.setX(-1)
if (self.keyMap["right"] != 0):
self.moveVector.setX(1)
if (self.keyMap["forward"] != 0):
self.moveVector.setY(1)
if (self.keyMap["backward"] != 0):
self.moveVector.setY(-1)

# Transform the move vector relatively to camera and apply it as motion
self.newPoint = startpos + self.moveVector
self.ralph.lookAt(self.newPoint)
self.newVector = render.getRelativeVector(base.camera, self.moveVector)
if self.newVector.length() > 1:
self.newVector.normalize()
self.newVector *= 5
self.newVector *= globalClock.getDt()
self.ralph.setPos(self.ralph.getPos() + self.newVector)``````

This is the corrected code, but there is a problem I’m facing: I can only make the character face a direction relative to himself and not the camera. He will look in many directions according to the keys I press, but if the camera rotates, he will be facing the wrong direction.

``````self.newPoint = startpos + self.moveVector
self.ralph.lookAt(self.newPoint)``````

This is the one bit that needs improving.

I forgot that the last time I posted here I said the problem was solved. Well, it isn’t as of yet. The post above has a new problem: how to make the character face the direction he is moving to relatively to the camera, which means if I press right, he will be always looking right even if circling around the camera.

EDIT: SOLVED!

``````def move(self, task):

# If the camera-left key is pressed, move camera left.
# If the camera-right key is pressed, move camera right.
base.camera.lookAt(self.ralph)
if (self.keyMap["cam-left"] != 0):
base.camera.setX(base.camera, - 15 * globalClock.getDt())
if (self.keyMap["cam-right"] != 0):
base.camera.setX(base.camera, + 15 * globalClock.getDt())

# Define variables to get zeroed out each frame
startpos = self.ralph.getPos()
self.moveVector = Vec3()

# Change move vector and look point by pressing keys
if (self.keyMap["left"] != 0):
self.moveVector.setX(-1)
if (self.keyMap["right"] != 0):
self.moveVector.setX(1)
if (self.keyMap["forward"] != 0):
self.moveVector.setY(1)
if (self.keyMap["backward"] != 0):
self.moveVector.setY(-1)

# Transform the move vector relatively to camera and apply it as motion
# as well as make Ralph face the direction he is running
self.newVector = render.getRelativeVector(base.camera, self.moveVector)
self.newPoint = startpos - self.newVector
if self.newVector.length() > 1:
self.newVector.normalize()
self.newVector *= 5
self.newVector *= globalClock.getDt()
self.ralph.setPos(self.ralph.getPos() + self.newVector)
self.ralph.lookAt(self.newPoint)``````