Controlling The Character with the Mouse.

Is there a way that i can take the roaming ralph demo and change it so that wherever the mouse clicks ralph will walk to?

Thanks for reading.

there sure is a way :slight_smile: it’s called coding.

Steps to make it work:
1.disable current ralph movement
2.use a ray to pick your target-point on the terrain.
3.rotate ralph to face the target point.
4.move ralph foreward + let him collide with the ground so he doesnt float.
5. if the distance to the targetpoint is small enough. let him stop.

i think pandasteer has point&click movement,too. there should be more than one example about how to do this. have you tried using the search function to digg them up?

Thanks so much,
just another question, when you say use a ray to define the point clicked,
what would i have to do to define the point clicked, i mean i have a ray and all but i just need to define the point clicked.

I’m unsure that I understand your question in full… Here is what you would do:

parent the ray to base.cam
use myRay.setFromLens(mouse_x, mouse_y)
that will point the ray at the 3D space inside the scene from the 2d mouse_x/mouse_y positions (0, 0) for center.

Then when the ray collides, using your collision handler, whichever one you have chosen, get the surface point as described in the manual, and then slowly move ralph there as desired

:smiley:

mouseNode = CollisionNode()
        mouseNP = camera.attachNewNode(mouseNode)
        mouseNode.setFromCollideMask(self.environ.getDefaultCollideMask())
        MoveRay = CollisionRay()
        mouseNode.addSolid(MoveRay)
        base.cTrav.addCollider(mouseNP, MoveHandler)
        MoveHandler = ColllisionHandlerEvent()

Would this be the right set up for a ray?

This looks correct to set up a ray, now you should fix it up with the camera by doing something like so:

mouseNode = CollisionNode()
mouseNP = camera.attachNewNode(mouseNode)
        mouseNode.setFromCollideMask(self.environ.getDefaultCollideMask())
MoveRay = CollisionRay()
mouseNode.addSolid(MoveRay)
base.cTrav.addCollider(mouseNP, MoveHandler)
queue = ColllisionHandlerQueue()

def moveRayTask(): # moves ray to mouse pointer
    #if the mouse is in the screen
    if base.mouseWatcherNode.hasMouse():
        #get the mouse position and store it
        mpos = base.mouseWatcherNode.getMouse()

        #now point the ray from the camera to the 3d space using setFromLens, it points the ray to the 3d spae of the 2d mouse position we give it, thus pointing it at the mouse
        MoveRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())

        # I changed the Collision Handler to a queue, you can get it to work with CollisionHandlerEvent too though I just find the queues easier to understand
        queue.sortEntries()
        # The above call sorts the objects that the ray collided with from nearest to farthest
        for i in range(queue.getNumEntries()):
            entry = queue.getEntry(i)
            print 'You clicked pos: ', entry.getSurfacePoint(render)

taskMgr.add(moveRayTask, 'moveRayTask')

as you can see, once you have a collision entry (https://www.panda3d.org/manual/index.php/Collision_Entries) you can go about getting the point of the entry, and even the face of the entry.

Also note that the second argument of entry.getSurfacePoint() is the nodepath to get the position ‘relative to’ so if your character is essentially parented to render, you would pass render to get the position relative to the render nodepath, this works in most cases.

Good luck :smiley: