Moving character without any key press

Hi. I want to be able to move my character forward without having to press any keys in-game but I can’t figure out how to. I have tried setting updating the player position like so :

  def move(self):
            while True:
                  self.player.setPos(self.player, 0,self.player.getY()+1,0)

which is how I had seen someone do it on an older post on here but that does not work for me as it gives me an error saying File "C:/Users/kianb/Documents/Work/DissertationProject/main.py", line 153, in move self.player.setPos(self.player, 0,self.player.getY()+1,0) AssertionError: !(pos.is_nan() || quat.is_nan() || scale.is_nan() || shear.is_nan()) at line 298 of c:\buildslave\sdk-windows-i386\build\panda\src\pgraph\transformState.cxx

Which I don’t quite understand. Is there a better way to move the player without having it controlled by someone?

Note that, as you have it there–and presuming no threading–the code will never exit the while-loop (until the program crashes or is shut down), and thus the program will never do anything but move the player. No input, no rendering, nothing.

It will also move the player increasingly fast, I believe, as on each loop it adds the player’s increasing y-coordinate to its current position.

(This is because it’s both setting the player’s position relative to itself and setting its position to be “said position + 1”. The first part, in broad strokes, means that it’s setting its position to be “its position + the given value”. (That’s slightly inaccurate, but for this conversation it’ll do.) However, “the given value” is “its position + 1”. As a result, it’s essentially adding its position twice, and the larger its position grows, the more it’ll be adding to its current position.)

Presuming that you’re using Panda’s default game-loop, I’d suggest making a task, and setting the player’s position within that task (ideally using the frame’s delta-time to control the speed of movement).

Something like this:

In your initialisation:

    # Specify the speed of the player. This is just a quick-and-dirty
    # way of doing it. The value is also arbitrary, and may call
    # for adjustment.
    self.playerSpeed = 10

    # Start up a task, which should call "movePlayer" each frame
    self.movementTask = taskMgr.add(self.movePlayer, "movement task")

Elsewhere:

def movePlayer(task):
    # Get the delta-time for the current frame
    dt = globalClock.getDt()

    # Set the player's position, relative to itself
    self.player.setPos(self.player, 0, self.playerSpeed*dt, 0)

    # Instruct the task to continue running
    return task.cont

I am getting the error that direct.task has no attribute cont ?

Really? Odd!

What versions of Panda and Python are you using?

I am using python version 3.8.3 and panda3d version 1.10.9

That should be fine, I believe. Could you show me your code then, please? That way I might see where the discrepancy lies.

here is the fucntion to get the player to move

    def move(self):
        dt = globalClock.getDt()
        self.player.setPos(self.player, 0,self.playerSpeed*dt,0 )
        return task.cont
    def __init__(self):
        ShowBase.__init__(self)
        self.playerSpeed = 10
        gltf.patch_loader(self.loader)  # allows use of .gltf files
        self.accept("escape", sys.exit)  # Escape quits
        self.player = None  # instantiate player
        self.cTrav = CollisionTraverser("base collision traverser")

        self.pusher = CollisionHandlerPusher()
        self.disable_mouse()  # disables mouse controls not actual mouse
        # setup path for models
        self.mydir = os.path.abspath(sys.path[0])
        self.mydir = Filename.fromOsSpecific(self.mydir).getFullpath()
        self.jsonDir = Filename(self.mydir, 'config/configs.json').toOsSpecific()
        self.set_background_color((.1, .1, .1, 1))
        self.enableParticles()
        self.setupGravity()
        self.loadPlayer()
        self.setupLights()
        self.loadGround()
        self.loadMaze()
        self.move = self.taskMgr.add(self.move(), "move")

That is my init where the task is called.

Ah! You’ve left out the “task” parameter. Python is thus presumably accessing some other thing named “task”–perhaps the module that contains the “Task”-class.

(And I did leave out the “self” parameter when I gave the sample code, above, for which I apologise.)

In short, your “move” method should look something like this, I believe:

def move(self, task):
    # Your code here

Thank you! that fixed it but my character walks backwards instead of forwards? sorry for asking but do you know how to fix this?

1 Like

At a guess, I would imagine that your character-model has been made facing the negative-y direction, and thus when moved in the positive-y direction appears to be moving backwards.

If so, then I’d suggest fixing this in the model, as it’s likely to cause the fewest issues in the long run.

However, a quick-fix would be to simply add a minus-sign in front of the value used in your call to “setPos”.

Thank you! I feel like it’s problem after problem now though! the character will walk forward but go through the walls? but if I control the character with WASD then the model will not clip through the walls. At first, I thought I was just the camera but after doing some debugging it is the character model which will clip through which I don’t understand because it does not if I am controlling the character?

Game-dev can be like that sometimes, I fear! ^^;

Hmm… There are a few possible reasons for such behaviour that I can see, depending on your setup.

So a few questions to start with:

Your walls–what collision-shapes do you use?

And your player–where is your player-collider relative to “self.player” in the hierarchy?

(It might perhaps be preferable for this to be a separate thread, by the way.)

The collision geometry is automatically generated using blend2bam so i am not 100% sure what geometry it is using and i am using fireclawthefox’s advanced character controller so again i am not 100% sure where the collider is relative to the player.

Well, to the first, is your collision geometry in Blender just a mesh? If so, then it’s likely coming out as CollisionPolygons, I daresay.

To the latter, what is “self.player”? Is it a character controller, or some sub-part of one, or something that moves one?

Also, when you say that the character moves through walls, does it pass through with no resistance, or is there a “hesitation” or “jitter” of some sort?

I believe that it is collision polygons for the maze model. self.player is in reference to the character controller. When I comment out the function which moves the player, the model will only peek through the wall and stop so I think that has something to do with the camera and not the player. When I uncomment that function, the model will walk through the maze with no jitters or hesitation almost as if there were no collision geometry around it.

To be clear: are you seeing an actual 3D model move through the wall, or just a camera-view?

In the former case, I think that it’s unlikely that the camera is affecting the model’s ability to move through the walls.

However, without a better idea of what’s going on in your code, it’s hard to be confident of what’s going wrong, I’m afraid.

It might be worth searching the hierarchies of your walls and your player-controller for all collision-nodes, and then calling “show” on them to make them visible. Further, it might be worth activating the visualisation of collisions. This might give you some clues as to what’s happening.

I am seeing the whole model go through the wall. I will post a link to a video to better show what is happening, i have made the collisions visible and as you can see from the video the player is not colliding with anything at all but like i previously mentioned when i commnet out the method which moves the player on its own, it stops moving through the walls link to video and project

Okay, looking at the video that I found in that link, I’m not seeing a model moving through the wall, only a camera. I wonder, then, whether the problem isn’t that the camera is being moved separately from the collider.

Perhaps start a new thread for this–so that others with similar issues might find it–and ping fireclawthefox about it in said thread.

1 Like

After some more investigating I found that it is the model that is moving but none of its collision geometry is moving with it. I have opened an issue on the character controller GitHub about it. Thank you for your help.

1 Like

Not a problem! I’m glad that you found somewhat at least of the source of the problem, and I hope that the issue is solved swiftly and easily! :slight_smile:

1 Like