[Solved] Animation not playing

Can anyone spot a problem in my code?
Problems:
BoxMan_stand seems to be ‘stuck’ on frame 1.
BoxMan_walk does not work at all- for some reason it plays BoxMan.egg (the rigging pose which isn’t animated at all)

I haven’t set any collision flags in maya.

BoxMan is a character in the rigging position, BoxMan_stand is an idle animation and BoxMan_walk is a walking animation. These are all seperate files converted from three .mb files using:
maya2egg2008 -a both -o “eggModels/FILE.egg” “mayaModels/FILE.mb”
(Where FILE is whichever scene I’m converting)

I’ve checked each .egg in pview and they all play correctly.

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.showbase.DirectObject import DirectObject
from direct.task import Task
from direct.actor import Actor
from direct.interval.IntervalGlobal import *
import math, sys

environ = loader.loadModel("models/environment")
environ.reparentTo(render)
environ.setScale(0.25,0.25,0.25)
environ.setPos(-8,42,0)

box1 = loader.loadModel("eggModels/box")
box1.reparentTo(render)
box1.setScale(1,1,1)
box1.setPos(-8,0,0)

box2 = loader.loadModel("eggModels/box")
box2.reparentTo(render)
box2.setScale(1,1,1)
box2.setPos(-8,0,3.9)

class World(DirectObject):
    def __init__(self):    
        self.BoxMan = Actor.Actor("eggModels/BoxMan",
                                  {"stand":"eggModels/BoxMan_stand",
                                   "walk":"eggModels/BoxMan_walk"})
        self.BoxMan.reparentTo(render)
        self.BoxMan.setPos(0,-10,0)
        #self.BoxMan.loop("stand")

        self.BoxMan.keyMap = {"forward":0} 
        self.accept("escape", sys.exit)
        self.accept("arrow_up", self.setKey, ["forward", 1]) 
        self.accept("arrow_up-up", self.setKey, ["forward", 0]) 

        taskMgr.add(self.UpdateBox, "UpdateBox")

    def setKey(self, key, value):
        self.BoxMan.keyMap[key] = value

    def UpdateBox(self, task):
        if self.BoxMan.keyMap["forward"]==1: 
            self.BoxMan.setPos(0,-10,0)
            self.BoxMan.stop()
            self.BoxMan.loop("walk")
        else:
            self.BoxMan.setPos(0,0,0)
            self.BoxMan.stop()
            self.BoxMan.loop("stand")
        return task.cont
   
base.camera.setPos(10,10,0)

w = World()

run()

Your egg files probably have different character names. When egging an actor, the animation and model need to have the same character name.

Try:
maya2egg -cn boxMan -o model.egg model.mb
maya2egg -cn boxMan -o anim.egg anim.mb

Thank you for replying!

Unfortunately -cn BoxMan didnd’t seem to have an effect. I also tried exporting model only for the BoxMan.mb, and then only the anim for the other two, still the same problem.

i havent played with animations around lately. but to me it looks like you simply restart your animation every frame. so all you would see would be frame 1 of the animation you’r playing.

Thank you for the reply,

Constantly restarting the animation would explain why I’m seeing the first frame only. I took a look at Roaming Ralph to see if my logic structure was different.

# If ralph is moving, loop the run animation.
        # If he is standing still, stop the animation.

        if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
            if self.isMoving is False:
                self.ralph.loop("run")
                self.isMoving = True
        else:
            if self.isMoving:
                self.ralph.stop()
                self.ralph.pose("walk",5)
                self.isMoving = False

The above code is in the move function which gets added to the task manager and returns Task.cont

After reading your post I can’t actually work out why Roaming Ralph’s animations actually work- it would make sense that the animation constantly restarts but for some reason it doesn’t.

Removing the self.BoxMan.stop() lines does not have an effect.

Still, the walk anim should be playing the first frame at least…

You should call start/loop commands only once. If you call them every frame, they will be restarted again and again. In Roaming Ralph there is a variable that says whether Ralph is currently running or not (self.isMoving). So, the start/loop commands are only called when he is not running, and the stop command - only he is running.
In your code they are called every frame.

Thank you! The stand animation is now working!

Now I just have to work out why the walk animation doesn’t play at all… Since stand and walk are essentially the same thing (i.e. a rigged and animated model) it should be working.

You should post the new code you made, otherwise my decisions could be wrong.

From the above-posted code I can guess, that the problem is still the same. While you hold down the forward key, the walk animation is restarted each frame over and over again (because the event is sent not only the first frame it is pressed, but each frame while the key is down).

Another thing, your actor will not actually “walk”, because self.BoxMan.setPos(0,-10,0) sets it the specified position relative to its parent. Therefore, it will just stand in (0,-10,0). If you want to move it further and further every frame, you much do something like: self.BoxMan.setPos(self.BoxMan, 0,-10,0). This will set your model -10 units along Y relative to its current position and rotation.

The setpos() was just a way of testing whether my if statements were executing (before I had any animations made). Thanks for that though, saves me having to look how to do it later.

class World(DirectObject):
    def __init__(self):    
        self.BoxMan = Actor.Actor("eggModels/BoxMan.egg",
                                  {"stand":"eggModels/BoxMan_stand.egg",
                                   "walk":"eggModels/BoxMan_walk.egg"})
        self.BoxMan.reparentTo(render)
        self.BoxMan.setPos(0,0,0)
        self.BoxMan.loop("stand")

        self.Running = False

        self.BoxMan.keyMap = {"forward":0}

        self.accept("escape", sys.exit)
        self.accept("arrow_up", self.setKey, ["forward", 1])
        self.accept("arrow_up-up", self.setKey, ["forward", 0])

        taskMgr.add(self.UpdateBox, "UpdateBox")
        taskMgr.add(self.setCamera, "CameraInitial")

    def setKey(self, key, value):
        self.BoxMan.keyMap[key] = value

    def UpdateBox(self, task):
        if self.BoxMan.keyMap["forward"]==1:
            self.BoxMan.setPos(0,-10,0)
            if not self.Running:
                self.BoxMan.loop("walk")# Does not play any frames, in BoxMan.egg postion
                self.Running = True
        else:
            self.BoxMan.setPos(0,0,0)
            if self.Running:
                self.BoxMan.loop("stand")# This now works.
                self.Running = False
        return task.cont
   
    def setCamera(self, task):
        base.camera.setPos(20,20,10)

(The imports and anything else outside of World() have not been changed from my first post)

I have just tried your code (replaces box with ralph, and stand animation with ralph’s run animation). It works just fine. So, the problem is in your models and animations.
Also, you will need to add

        base.camera.lookAt(self.BoxMan, 0, 0, 0)
        return task.cont

to the setCamera method, to make the camera look at the self.BoxMan, and be updated every frame.

Thanks for your help everyone! I’ll fiddle around with the models, maybe make a new one…