java.lang.IllegalArgumentException: Cannot find animation named

I would like to have help with a error I’m are currently having for the Jmonkey Engine 3 and possibly help others if they are getting the same or similar message. I keep getting this error, when I run/build the project


But when I put the model in the scene composer and go into AnimControl the animations when I play them work.

The Code can be uploaded to if requested.

Thank you

1 Like

How do you create your channel?
It actually would have been interesting to see the code that is just behind the dialog box :stuck_out_tongue:

1 Like

My whole code (Thanks for helping!)

Also what did you mean by that :p?


package mygame;

import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.light.PointLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;

    
/**
 * test
 * @author 
 */
public class Test1 extends SimpleApplication 
 implements AnimEventListener {
 private AnimChannel channel;
 private AnimControl control;
 Node player;
    public static void main(String[] args) {
        Test1 app = new Test1();
        app.start();
    }
 

    @Override
    public void simpleInitApp() {
     initKeys();
     
     Spatial Scene = assetManager.loadModel("Models/Hotelroom/Hotelroom.blend");
     rootnode.attachChild(Scene);
     
    DirectionalLight sun = new DirectionalLight();
    sun.setDirection((new Vector3f(-.1f, -.1f, -.1f)).normalizeLocal());
    sun.setColor(ColorRGBA.White);
    rootNode.attachChild(Scene);
    rootNode.addLight(sun);//if you comment this out,all  is darkness Yes Cracked it!
     
    player = (Node) assetManager.loadModel("Models/Main Chr/Cube.mesh.j3o");
    player.setLocalTranslation(20f, 1100f, 90f);
    player.scale(1.60f);
    rootnode.attachChild(player);
    control = player.getControl(AnimControl.class);
    
    control.addListener(this);
    channel = control.createChannel();
    channel.setAnim("Idle");
    PointLight lamp = new PointLight();
    lamp.setPosition((new Vector3f(1f, 900f, 900f)).normalizeLocal());
    lamp.setColor(ColorRGBA.White);
    rootNode.attachChild(player);
    rootnode.addLight(lamp); //if you comment this out,all is darkness
    }
 public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
     if (animName.equals("Walk")) {
        channel.setAnim("Idle",0.50f);
        channel.setLoopMode(LoopMode.DontLoop);
        channel.setSpeed(1f);
    }
  }

 public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
      //unused
    }
    
private void initKeys() {
 inputManager.addMapping("Walk", new KeyTrigger(KeyInput.KEY_SPACE));
 inputManager.addListener(actionListener, "Walk");
}
private ActionListener actionListener = new ActionListener() {
  public void onAction(String name, boolean keyPressed, float tpf) {
    if (name.equals("Walk") && !keyPressed) {
    if (!channel.getAnimationName().equals("Walk")) {
      channel.setAnim("Walk", 0.50f);
      channel.setLoopMode(LoopMode.Loop);
       }
      }
    }
  };
}
1 Like
1 Like

Yeah “:p” used to be turned into a smiley before, but I guess the recent forum change took away that feature. Never mind.

The code looks ok to me.
Are you absolutely sure you’re loading the same model as the one exposed in the picture? Because that’d be the only explanation I would think of.

1 Like

I may have made the AnimEvent Listener abstract if that may affect by mistake
And yes I’m sure I am trying loading the exact model.

Here is the error in the bottom box when I try to run the file/project.

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.IllegalArgumentException: Cannot find animation named: ‘Idle’
at com.jme3.animation.AnimChannel.setAnim(AnimChannel.java:252)
at com.jme3.animation.AnimChannel.setAnim(AnimChannel.java:286)
at mygame.Test1.simpleInitApp(Test1.java:60)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207)
at java.lang.Thread.run(Thread.java:744)

1 Like

Here is the WHOLE AnimChannel.java code

public final class AnimChannel {

private static final float DEFAULT_BLEND_TIME = 0.15f;

private AnimControl control;

private BitSet affectedBones;

private Animation animation;
private Animation blendFrom;
private float time;
private float speed;
private float timeBlendFrom;
private float blendTime;
private float speedBlendFrom;
private boolean notified=false;

private LoopMode loopMode, loopModeBlendFrom;

private float blendAmount = 1f;
private float blendRate   = 0;

private static float clampWrapTime(float t, float max, LoopMode loopMode){
    if (t == 0) {
        return 0; // prevent division by 0 errors
    }
    
    switch (loopMode) {
        case Cycle:
            boolean sign = ((int) (t / max) % 2) != 0;
            float result;

// if (t < 0){
// result = sign ? t % max : -(max + (t % max));
// } else {
// NOTE: This algorithm seems stable for both high and low
// tpf so for now its a keeper.
result = sign ? -(max - (t % max)) : t % max;
// }

// if (result <= 0 || result >= max) {
// System.out.println("SIGN: " + sign + ", RESULT: " + result + ", T: " + t + ", M: " + max);
// }

            return result;
        case DontLoop:
            return t &gt; max ? max : (t &lt; 0 ? 0 : t);
        case Loop:
            return t % max;
    }
    return t;

// if (max == Float.POSITIVE_INFINITY)
// return t;
//
// if (t < 0f){
// //float tMod = -(-t % max);
// switch (loopMode){
// case DontLoop:
// return 0;
// case Cycle:
// return t;
// case Loop:
// return max - t;
// }
// }else if (t > max){
// switch (loopMode){
// case DontLoop:
// return max;
// case Cycle:
// return -(2f * max - t) % max;
// case Loop:
// return t % max;
// }
// }
//
// return t;
}

AnimChannel(AnimControl control){
    this.control = control;
}

/**
 * Returns the parent control of this AnimChannel.
 * 
 * @return the parent control of this AnimChannel.
 * @see AnimControl
 */
public AnimControl getControl() {
    return control;
}

/**
 * @return The name of the currently playing animation, or null if
 * none is assigned.
 *
 * @see AnimChannel#setAnim(java.lang.String) 
 */
public String getAnimationName() {
    return animation != null ? animation.getName() : null;
}

/**
 * @return The loop mode currently set for the animation. The loop mode
 * determines what will happen to the animation once it finishes
 * playing.
 * 
 * For more information, see the LoopMode enum class.
 * @see LoopMode
 * @see AnimChannel#setLoopMode(com.jme3.animation.LoopMode)
 */
public LoopMode getLoopMode() {
    return loopMode;
}

/**
 * @param loopMode Set the loop mode for the channel. The loop mode
 * determines what will happen to the animation once it finishes
 * playing.
 *
 * For more information, see the LoopMode enum class.
 * @see LoopMode
 */
public void setLoopMode(LoopMode loopMode) {
    this.loopMode = loopMode;
}

/**
 * @return The speed that is assigned to the animation channel. The speed
 * is a scale value starting from 0.0, at 1.0 the animation will play
 * at its default speed.
 *
 * @see AnimChannel#setSpeed(float)
 */
public float getSpeed() {
    return speed;
}

/**
 * @param speed Set the speed of the animation channel. The speed
 * is a scale value starting from 0.0, at 1.0 the animation will play
 * at its default speed.
 */
public void setSpeed(float speed) {
    this.speed = speed;
    if(blendTime&gt;0){
        this.speedBlendFrom = speed;
        blendTime = Math.min(blendTime, animation.getLength() / speed);  
        blendRate = 1/ blendTime;
    }
}

/**
 * @return The time of the currently playing animation. The time
 * starts at 0 and continues on until getAnimMaxTime().
 *
 * @see AnimChannel#setTime(float)
 */
public float getTime() {
    return time;
}

/**
 * @param time Set the time of the currently playing animation, the time
 * is clamped from 0 to {@link #getAnimMaxTime()}. 
 */
public void setTime(float time) {
    this.time = FastMath.clamp(time, 0, getAnimMaxTime());
}

/**
 * @return The length of the currently playing animation, or zero
 * if no animation is playing.
 *
 * @see AnimChannel#getTime()
 */
public float getAnimMaxTime(){
    return animation != null ? animation.getLength() : 0f;
}

/**
 * Set the current animation that is played by this AnimChannel.
 * &lt;p&gt;
 * This resets the time to zero, and optionally blends the animation
 * over <code>blendTime</code> seconds with the currently playing animation.
 * Notice that this method will reset the control's speed to 1.0.
 *
 * @param name The name of the animation to play
 * @param blendTime The blend time over which to blend the new animation
 * with the old one. If zero, then no blending will occur and the new
 * animation will be applied instantly.
 */
public void setAnim(String name, float blendTime){
    if (name == null)
        throw new IllegalArgumentException("name cannot be null");

    if (blendTime &lt; 0f)
        throw new IllegalArgumentException("blendTime cannot be less than zero");

    Animation anim = control.animationMap.get(name);
    if (anim == null)
        throw new IllegalArgumentException("Cannot find animation named: '"+name+"'");

    control.notifyAnimChange(this, name);

    if (animation != null &amp;&amp; blendTime &gt; 0f){
        this.blendTime = blendTime;
        // activate blending
        blendTime = Math.min(blendTime, anim.getLength() / speed);            
        blendFrom = animation;
        timeBlendFrom = time;
        speedBlendFrom = speed;
        loopModeBlendFrom = loopMode;
        blendAmount = 0f;
        blendRate   = 1f / blendTime;
    }else{
        blendFrom = null;
    }

    animation = anim;
    time = 0;
    speed = 1f;
    loopMode = LoopMode.Loop;
    notified = false;
}

/**
 * Set the current animation that is played by this AnimChannel.
 * &lt;p&gt;
 * See {@link #setAnim(java.lang.String, float)}.
 * The blendTime argument by default is 150 milliseconds.
 * 
 * @param name The name of the animation to play
 */
public void setAnim(String name){
    setAnim(name, DEFAULT_BLEND_TIME);
}

/**
 * Add all the bones of the model's skeleton to be
 * influenced by this animation channel.
 */
public void addAllBones() {
    affectedBones = null;
}

/**
 * Add a single bone to be influenced by this animation channel.
 */
public void addBone(String name) {
    addBone(control.getSkeleton().getBone(name));
}

/**
 * Add a single bone to be influenced by this animation channel.
 */
public void addBone(Bone bone) {
    int boneIndex = control.getSkeleton().getBoneIndex(bone);
    if(affectedBones == null) {
        affectedBones = new BitSet(control.getSkeleton().getBoneCount());
    }
    affectedBones.set(boneIndex);
}

/**
 * Add bones to be influenced by this animation channel starting from the
 * given bone name and going toward the root bone.
 */
public void addToRootBone(String name) {
    addToRootBone(control.getSkeleton().getBone(name));
}

/**
 * Add bones to be influenced by this animation channel starting from the
 * given bone and going toward the root bone.
 */
public void addToRootBone(Bone bone) {
    addBone(bone);
    while (bone.getParent() != null) {
        bone = bone.getParent();
        addBone(bone);
    }
}

/**
 * Add bones to be influenced by this animation channel, starting
 * from the given named bone and going toward its children.
 */
public void addFromRootBone(String name) {
    addFromRootBone(control.getSkeleton().getBone(name));
}

/**
 * Add bones to be influenced by this animation channel, starting
 * from the given bone and going toward its children.
 */
public void addFromRootBone(Bone bone) {
    addBone(bone);
    if (bone.getChildren() == null)
        return;
    for (Bone childBone : bone.getChildren()) {
        addBone(childBone);
        addFromRootBone(childBone);
    }
}

BitSet getAffectedBones(){
    return affectedBones;
}

public void reset(boolean rewind){
    if(rewind){
        setTime(0);        
        if(control.getSkeleton()!=null){
            control.getSkeleton().resetAndUpdate();
        }else{
            TempVars vars = TempVars.get();
            update(0, vars);
            vars.release();    
        }
    }
    animation = null;
   // System.out.println("Setting notified false");
    notified = false;
}

void update(float tpf, TempVars vars) {
    if (animation == null)
        return;

    if (blendFrom != null &amp;&amp; blendAmount != 1.0f){
        // The blendFrom anim is set, the actual animation
        // playing will be set 

// blendFrom.setTime(timeBlendFrom, 1f, control, this, vars);
blendFrom.setTime(timeBlendFrom, 1f - blendAmount, control, this, vars);

        timeBlendFrom += tpf * speedBlendFrom;
        timeBlendFrom = clampWrapTime(timeBlendFrom,
                                      blendFrom.getLength(),
                                      loopModeBlendFrom);
        if (timeBlendFrom &lt; 0){
            timeBlendFrom = -timeBlendFrom;
            speedBlendFrom = -speedBlendFrom;
        }

        blendAmount += tpf * blendRate;
        if (blendAmount &gt; 1f){
            blendAmount = 1f;
            blendFrom = null;
        }
    }
    
    animation.setTime(time, blendAmount, control, this, vars);
    time += tpf * speed;
    if (animation.getLength() &gt; 0){
        if (!notified &amp;&amp; (time &gt;= animation.getLength() || time &lt; 0)) {
            if (loopMode == LoopMode.DontLoop) {
                // Note that this flag has to be set before calling the notify
                // since the notify may start a new animation and then unset
                // the flag.
                notified = true;
            }
            control.notifyAnimCycleDone(this, animation.getName());
        } 
    }
    time = clampWrapTime(time, animation.getLength(), loopMode);
    if (time &lt; 0){
        // Negative time indicates that speed should be inverted
        // (for cycle loop mode only)
        time = -time;
        speed = -speed;
    }
}

}