How to Make Actor Turn?

So as the title suggests I want to make my panda actor turn when the right or left arrow keys are pressed but am not sure how to go about this. Right now the actor can only move forward when the up arrow key is pressed.

here’s a link to my code if anyone needs it --> https://paste.pythondiscord.com/egagiweyuf.py

Thanks!
EDIT: Followed the solutions given to me but two more problems popped up

  1. When I press the arrow key it turns the actor but I can only do it once
  2. It doesn’t straight to the direction it has been turned to

EDIT2: Fixed all the problems, thanks everyone!

To rotate the actor you can set it’s rotation value via

self.pandaActor.setR(rotationValue)

The rotation value is set in degree, so it’s 0-360 while higher and lower (e.g. negative) values will still work and rotate the actor accordingly.

As a side note, you could also take a look at the Roaming Ralph demo that usually ships with the Panda3D installation. There you can also see how you can set up tasks to move the actor instead of having to press the button again for each step.

A quick note: Depending on the axis about which you want your actor to rotate, you may want “setH” instead of “setR”.

On another note, if a tutorial might be of use to you, I suggest perhaps taking a look at my “Panda3D beginner’s tutorial”: it covers the fundamentals of using the engine (including things like turning a character) by way of constructing a simple game, all the way through to building a distributable version.

If you’re interested, you should find it here:

So I tried your solution but with setH as Thaumaturge suggested and it worked! But now I am experiencing two more problems.

  1. When I press the arrow key it turns the actor but I can only do it once
  2. It doesn’t straight to the direction it has been turned to

Can anyone please help? Thanks again!

1) Calling “setH” will simply set the direction in which your model is facing. What you (presumably) want is for the model to face a certain angle relative to its current direction. That is, you want it to not simply face a given direction, but to turn.

To that end, there are two basic options:

First, you could set its angle relative to itself. In Panda3D, many methods like “setH” accept an optional first parameter that specifies a NodePath that the primary parameter is understood to be relative to. In this case, we want the value to be relative to the model itself, so we pass in the model itself as that optional first parameter. Something like this:

self.myModel.setH(self.myModel, 10)

I think that this may come with caveats when scaling factors are applied to the model, however; I’m pretty confident that this is the case when setting position, but I’m not sure that it applies when setting direction.

The second option is similar, but instead of setting the model’s angle relative to itself, we simply get its current angle and add the turn-value to it. Something like this:

self.myModel.setH(self.myModel.getH() + 10)

(A quick note: if you’re not using a fixed clock-rate, you might want to consider multiplying turns and movements by the time since the last program update. You can get this via the “global clock”, as described here: https://www.panda3d.org/manual/?title=The_Global_Clock

2) I’m not sure of what you mean. Do you mean that it doesn’t move in the direction in which it’s facing?

If so, then based on the code that you provide, it looks like this is because you’re moving the object relative to its parent, rather than relative to itself. Thus its direction has no effect on the direction in which it’s being moved.

Thanks your first solution worked for my first problem, and to clarify things it doesn’t move in the direction it’s facing. Could you elaborate on your solution?

Simply calling setY doesnt automatically respects its rotation to move it on the “foerward vector” as you probably want. What you want is calling model.setY(model, amountOfMovement)

As it stands, you’re setting the model’s position. Since you’re not specifying a NodePath that the new position is relative to, you’re effectively setting that position relative to the model’s parent NodePath. As a result, you’re moving it along that parent NodePath’s y-axis, not the model’s y-axis. And since the parent NodePath hasn’t been rotated, that direction remains the same regardless of how you rotate your model.

The solutions here are pretty similar to those that I gave for rotation, above: you can either place the object relative to itself (as wolf shows, above, and again with the caveat that scaling the model might interfere with the results), or you can get the model’s direction-vector and place it along that vector.

so I tried doing

 self.pandaActor.setY(self.pandaActor, -1)

instead of

 self.pandaActor.setY(self.pandaActor.getY() + -1)

but when tried it the panda just played the walking animation but didn’t move, does anyone know why?

Do you have a scale applied to the model?

Sorry, I’m not sure what you mean?

try self.pandaActor.setY(self.pandaActor, -200)
As your model has a scale of 0.005 you also need to scale up the amount of movement as it is now relative to the models scale.

Thanks a ton! It worked perfectly!!

To elaborate a bit:

Looking back at your code, I note this line:

self.pandaActor.setScale(0.005, 0.005, 0.005)

In this, you’re scaling the model–applying a scale; changing its size. However, scaling a NodePath affects positions made relative to it. Thus, if you have a model with a scale of 0.1, and you move it by 2 units, it will move a total of 0.2 units relative to its parent.

Ah ok, I have a better understanding now.

1 Like