I’m learning Panda3D and I’m trying some various stuff. I made a little simulation with some roaming animals witch just go to a random point, and when they reach it move to another one.
I was using “actor.setPos(actor, 0, dy, 0)” in task to move between 2 point (and that worked well).
After that, I remember the moving panda from the manual, and I try to figure if I could use some “Sequence” or just “moveInterval” and find a solution to avoid testing in my python code if the animal reach the destination on every frame.
I finally come with this :
I define a first loop animation, I predict his duration, and plan to define a new loop animation after the first one finish one loop.
I was looking if there is a way to do something like planning a task (with the “taskMgr” or something) that run after an actor done one loop of “moveInterval” or reached a position.
Did such stuff exist or have I to completely code this in python ?
If you want to use intervals, then consider creating a Sequence, the final element of which calls a method that restarts the movement.
(I’m not sure that it’s a good idea to re-create the sequence while the current sequence is still running–although I stand for correction on this–and so suggest having the method called use “doMethodLater” with a duration of zero (meaning that it should fire on the next frame) to call the actual restart method.)
Try s.sequence.start() instead–that might be part of the reason that your creatures are bouncing around when you don’t explicitly “finish” the sequence; using “start” should instruct the sequence to run just once, rather than repeat, as you’re currently instructing it, I believe.
What I was suggestion was something like this, I think:
def newDestinations(s):
# As I said, I think that you can do without
# the "finish" if you use "start" below
s.target = randomPoint()
dt = (s.getPos() - s.target).length() / s.speed
# Note the change in method called
s.sequence = Sequence(s.posInterval(dt, s.target),
Func(s.sequenceDone))
s.lookAt(*s.target)
# Again, I'm using "start" instead of "loop"
# since we (presumably) want the sequence
# to run only once.
s.sequence.start()
def sequenceDone(s):
# Call "newDestinations" on the next frame, hopefully
# allowing the sequence to clean up before we create
# a new one.
taskMgr.doMethodLater(0, s.newDestinations, "restart")
I think I get what you mean. It’s the first time I use such engine, and in my mind when I write ‘sequence.finish()’ it’s done before the next line is execute.
I’m not entirely certain, but not much, I don’t think; at the least the former seems slightly easier to me (especially as it’s easy to forget to include that “task.done”).