Mixamo animated character + physic resulting error [SOLVED]

That’s because you may of forgot to add back the AnimEventListener after ActionListener and to uncomment this?

/**
    public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
        if (channel == shootingChannel) {
            channel.setAnim("idle");
        }
    }
*/

Edit: You also left off your channels in the adapter. Re-read what I posted. Animations don’t work without channels…
https://jmonkeyengine.github.io/wiki/jme3/beginner/hello_animation.html#animation-controller-and-channel

1 Like

Sorry paul, didn’t know you were responding.

1 Like

No, it’s fine… you are closer to the problem than I am. I just see “new Java developer struggling” and can’t help but prod a little as I drive by.

1 Like

You can look at the log by the path “{userhome}/.jmonkeybuilder/log” in this case :slight_smile:

1 Like

okay. somthing like this…

WARNING 03:45:47:792 FileIconManager: not found image for contentType null and path C:\Users\burunghantu\Documents\bootmonkey\MyGame\assets\Models\erika\erika.bin
WARNING 03:45:47:824 FileIconManager: not found image for contentType null and path C:\Users\burunghantu\Documents\bootmonkey\MyGame\assets\Models\erika\erika.blend1
WARNING 03:45:47:843 FileIconManager: not found image for contentType null and path C:\Users\burunghantu\Documents\bootmonkey\MyGame\assets\Models\erika\erika.mtl

Maybe because I copied and pasted the model from one project to another? so I save my blend file to the project asset folder, cahnge the path of textures to where I save it in project folder. Then export as gltf again to project asset folder. Tried to convert again j3o. here’s I got with the log…

WARNING 04:01:00:842 FileIconManager: not found image for contentType null and path C:\Users\burunghantu\Documents\bootmonkey\MyGame\assets\Models\erika\erika.bin
WARNING 04:01:00:906 FileIconManager: not found image for contentType null and path C:\Users\burunghantu\Documents\bootmonkey\MyGame\assets\Models\erika\erika.blend1

1 Like

I started over. I still lost. This is the code…


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.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh.Type;
import com.jme3.effect.shapes.EmitterSphereShape;
import com.jme3.input.ChaseCamera;
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.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.SceneGraphVisitorAdapter;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.terrain.geomipmap.TerrainLodControl;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.heightmap.AbstractHeightMap;
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import com.jme3.util.SkyFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A walking animated character followed by a 3rd person camera on a terrain with LOD.
 * @author normenhansen
 */
public class CharWalk extends SimpleApplication implements ActionListener, AnimEventListener {

    private BulletAppState bulletAppState;
    private static final Logger LOG = Logger.getLogger(CharWalk.class.getName());    
    //character
    CharacterControl character;
    Node model;
    //temp vectors
    Vector3f walkDirection = new Vector3f();
    //terrain
    TerrainQuad terrain;
    RigidBodyControl terrainPhysicsNode;
    //Materials
    Material matRock;
    Material matBullet;
    //animation
    AnimChannel animationChannel;
//    AnimChannel shootingChannel;
    AnimControl animationControl;
    float airTime = 0;
    //camera
    boolean left = false, right = false, up = false, down = false;
    ChaseCamera chaseCam;


    public static void main(String[] args) {
        CharWalk app = new CharWalk();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        bulletAppState = new BulletAppState();
        bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
        stateManager.attach(bulletAppState);
//        bulletAppState.setDebugEnabled(true);    
        setupKeys();

        createLight();
        createSky();
        createTerrain();

        createCharacter();
        setupChaseCamera();
        setupAnimationController();
    //    setupFilter();
    }


    private PhysicsSpace getPhysicsSpace() {
        return bulletAppState.getPhysicsSpace();
    }

    private void setupKeys() {
        inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T));
        inputManager.addListener(this, "wireframe");
        inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
        inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
        inputManager.addMapping("CharUp", new KeyTrigger(KeyInput.KEY_W));
        inputManager.addMapping("CharDown", new KeyTrigger(KeyInput.KEY_S));
        inputManager.addMapping("CharSpace", new KeyTrigger(KeyInput.KEY_SPACE));
        inputManager.addMapping("CharShoot", new KeyTrigger(KeyInput.KEY_X));
        inputManager.addListener(this, "CharLeft");
        inputManager.addListener(this, "CharRight");
        inputManager.addListener(this, "CharUp");
        inputManager.addListener(this, "CharDown");
        inputManager.addListener(this, "CharSpace");
        inputManager.addListener(this, "CharShoot");
    }

    private void createLight() {
        Vector3f direction = new Vector3f(-0.1f, -0.7f, -1).normalizeLocal();
        DirectionalLight dl = new DirectionalLight();
        dl.setDirection(direction);
        dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
        rootNode.addLight(dl);
    }

    private void createSky() {
		Texture west = assetManager.loadTexture("Textures/Sky/Lagoon/slice_0_0.jpg");
		Texture east = assetManager.loadTexture("Textures/Sky/Lagoon/slice_0_1.jpg");
		Texture north = assetManager.loadTexture("Textures/Sky/Lagoon/slice_0_0.jpg");
		Texture south = assetManager.loadTexture("Textures/Sky/Lagoon/slice_0_1.jpg");
		Texture up = assetManager.loadTexture("Textures/Sky/Lagoon/blue.jpg");
		Texture down = assetManager.loadTexture("Textures/Sky/Lagoon/blue.jpg");

    Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down);
	rootNode.attachChild(sky);
    }

    private void createTerrain() {
        matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
        matRock.setBoolean("useTriPlanarMapping", false);
        matRock.setBoolean("WardIso", true);
        matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
        Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/island512.png");
        Texture grass = assetManager.loadTexture("Textures/Terrain/splat/snow.jpg");
        grass.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap", grass);
        matRock.setFloat("DiffuseMap_0_scale", 64);
        Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
        dirt.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap_1", dirt);
        matRock.setFloat("DiffuseMap_1_scale", 16);
        Texture rock = assetManager.loadTexture("Textures/Terrain/splat/sand.jpg");
        rock.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap_2", rock);
        matRock.setFloat("DiffuseMap_2_scale", 128);
        Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/normal.jpg");
        normalMap0.setWrap(WrapMode.Repeat);
        Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/normal.png");
        normalMap1.setWrap(WrapMode.Repeat);
        Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/normal.png");
        normalMap2.setWrap(WrapMode.Repeat);
        matRock.setTexture("NormalMap", normalMap0);
        matRock.setTexture("NormalMap_1", normalMap2);
        matRock.setTexture("NormalMap_2", normalMap2);

        AbstractHeightMap heightmap = null;
        try {
            heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f);
            heightmap.load();

        } catch (Exception e) {
            e.printStackTrace();
        }

        terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
        List<Camera> cameras = new ArrayList<Camera>();
        cameras.add(getCamera());
        TerrainLodControl control = new TerrainLodControl(terrain, cameras);
        terrain.addControl(control);
        terrain.setMaterial(matRock);
        terrain.setLocalScale(new Vector3f(2, 2, 2));

        terrainPhysicsNode = new RigidBodyControl(CollisionShapeFactory.createMeshShape(terrain), 0);
        terrain.addControl(terrainPhysicsNode);
        rootNode.attachChild(terrain);
        getPhysicsSpace().add(terrainPhysicsNode);
    }

    private void createCharacter() {
        CapsuleCollisionShape capsule = new CapsuleCollisionShape(1f, 4f);
        character = new CharacterControl(capsule, 0.01f);
		character.setJumpSpeed(20);
		character.setFallSpeed(35);
		character.setGravity(30);		
        model = (Node) assetManager.loadModel("Models/erika/erika.j3o");
        model.setLocalScale(3.5f);
        model.addControl(character);
        character.setPhysicsLocation(new Vector3f(-140, 40, -10));
        rootNode.attachChild(model);
        getPhysicsSpace().add(character);
    }

    private void setupChaseCamera() {
        flyCam.setEnabled(false);
        chaseCam = new ChaseCamera(cam, model, inputManager);
    }

    private void setupAnimationController() {
        
    model.depthFirstTraversal(new SceneGraphVisitorAdapter() {
        @Override
        public void visit(Node node) {
            if (node.getControl(AnimControl.class) != null) {
                animationControl = node.getControl(AnimControl.class);
                animationControl.addListener(this);
                animationChannel = animationControl.createChannel();

            }
        }
    });
    
            if (animationControl == null) {
            LOG.log(Level.SEVERE, "No AnimControl {0}", model);
            throw new RuntimeException();
        }
        
        
//        animationControl = model.getControl(AnimControl.class);
//        animationControl.addListener(this);
//        animationChannel = animationControl.createChannel();
//        shootingChannel = animationControl.createChannel();
//        shootingChannel.addBone(animationControl.getSkeleton().getBone("uparm.right"));
//       shootingChannel.addBone(animationControl.getSkeleton().getBone("arm.right"));
//        shootingChannel.addBone(animationControl.getSkeleton().getBone("hand.right"));
    }

    @Override
    public void simpleUpdate(float tpf) {
        Vector3f camDir = cam.getDirection().clone().multLocal(0.1f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f);
        camDir.y = 0;
        camLeft.y = 0;
        walkDirection.set(0, 0, 0);
        if (left) {
            walkDirection.addLocal(camLeft);
        }
        if (right) {
            walkDirection.addLocal(camLeft.negate());
        }
        if (up) {
            walkDirection.addLocal(camDir);
        }
        if (down) {
            walkDirection.addLocal(camDir.negate());
        }
        if (!character.onGround()) {
            airTime = airTime + tpf;
        } else {
            airTime = 0;
        }
        if (walkDirection.length() == 0) {
//            if (!"idle".equals(animationChannel.getAnimationName())) {
//                animationChannel.setAnim("idle", 1f);
//            }
        } else {
            character.setViewDirection(walkDirection);
            if (airTime > .3f) {
//                if (!"idle".equals(animationChannel.getAnimationName())) {
//                    animationChannel.setAnim("idle");
//                }
//            } else if (!"Walk".equals(animationChannel.getAnimationName())) {
//                animationChannel.setAnim("Walk", 0.7f);
            }
        }
        character.setWalkDirection(walkDirection);
    }

    public void onAction(String binding, boolean value, float tpf) {
        if (binding.equals("CharLeft")) {
            if (value) {
                left = true;
            } else {
                left = false;
            }
        } else if (binding.equals("CharRight")) {
            if (value) {
                right = true;
            } else {
                right = false;
            }
        } else if (binding.equals("CharUp")) {
            if (value) {
                up = true;
            } else {
                up = false;
            }
        } else if (binding.equals("CharDown")) {
            if (value) {
                down = true;
            } else {
                down = false;
            }
        } else if (binding.equals("CharSpace")) {
            character.jump();
//        } else if (binding.equals("CharShoot") && !value) {
//            bulletControl();
        }
    }



/**
    public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
        if (channel == shootingChannel) {
            channel.setAnim("idle");
        }
    }

    public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
    }

    @Override
    public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
*/
}

1 Like

You still have onAnimCycleDone and onAnimChange commented out.

Note that you now have two onAnimCycleDone methods, remove the second one.

I have never seen those warnings before.

I have never seen anyone use a .bin file for a model.

The file .blend1 looks to me to be a backup file also. Blender files end with the extension .blend.

https://jmonkeyengine.github.io/wiki/jme3/intermediate/file_types.html#toolbar

You are fast approaching the un-helpable stage because you are making errors that require you to actually learn the java programming language.

I will give you a link to the best tool for learning java there is. Don’t be insulted by the name, its not meant as a slur. Your buying the author, Doug Lowe, not the name.
https://www.amazon.com/Java-All-One-Dummies-Doug/dp/1119247799/ref=sr_1_1?ie=UTF8&qid=1513735776&sr=8-1&keywords=java+for+dummies

1 Like

The log is from jMB what @javasabr asked. I forgot to mention that. I even don’t know how I have that .bin file.
About my noob-ness nothing i can say about that. thanks for the help. i think I make a litle progress but really worthy for me.

Edit: probably the .bin file is made when I export from blender to gltf.

1 Like

This is quite close. Only, my model still flying, and walk animation stop suddenly at start cahnge to idle then to walk again at the end.
I do like this…


/**
 * A walking animated character followed by a 3rd person camera on a terrain with LOD.
 * @author normenhansen
 */
public class CharWalk extends SimpleApplication implements ActionListener, AnimEventListener {

    private BulletAppState bulletAppState;
    private static final Logger LOG = Logger.getLogger(CharWalk.class.getName());    
    //character
    CharacterControl character;
    Node model;
    //temp vectors
    Vector3f walkDirection = new Vector3f();
    //terrain
    TerrainQuad terrain;
    RigidBodyControl terrainPhysicsNode;
    //Materials
    Material matRock;
    Material matBullet;
    //animation
    AnimChannel animationChannel;
//    AnimChannel shootingChannel;
    AnimControl animationControl;
    float airTime = 0;
    //camera
    boolean left = false, right = false, up = false, down = false;
    ChaseCamera chaseCam;


    public static void main(String[] args) {
        CharWalk app = new CharWalk();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        bulletAppState = new BulletAppState();
        bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
        stateManager.attach(bulletAppState);
        bulletAppState.setDebugEnabled(true);    
        setupKeys();

        createLight();
        createSky();
        createTerrain();

        createCharacter();
        setupChaseCamera();
        setupAnimationController();
    //    setupFilter();
    }


    private PhysicsSpace getPhysicsSpace() {
        return bulletAppState.getPhysicsSpace();
    }

    private void setupKeys() {
        inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T));
        inputManager.addListener(this, "wireframe");
        inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
        inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
        inputManager.addMapping("CharUp", new KeyTrigger(KeyInput.KEY_W));
        inputManager.addMapping("CharDown", new KeyTrigger(KeyInput.KEY_S));
        inputManager.addMapping("CharSpace", new KeyTrigger(KeyInput.KEY_SPACE));
        inputManager.addMapping("CharShoot", new KeyTrigger(KeyInput.KEY_X));
        inputManager.addListener(this, "CharLeft");
        inputManager.addListener(this, "CharRight");
        inputManager.addListener(this, "CharUp");
        inputManager.addListener(this, "CharDown");
        inputManager.addListener(this, "CharSpace");
        inputManager.addListener(this, "CharShoot");
    }

    private void createLight() {
        Vector3f direction = new Vector3f(-0.1f, -0.7f, -1).normalizeLocal();
        DirectionalLight dl = new DirectionalLight();
        dl.setDirection(direction);
        dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
        rootNode.addLight(dl);
    }

    private void createSky() {
		Texture west = assetManager.loadTexture("Textures/Sky/Lagoon/slice_0_0.jpg");
		Texture east = assetManager.loadTexture("Textures/Sky/Lagoon/slice_0_1.jpg");
		Texture north = assetManager.loadTexture("Textures/Sky/Lagoon/slice_0_0.jpg");
		Texture south = assetManager.loadTexture("Textures/Sky/Lagoon/slice_0_1.jpg");
		Texture up = assetManager.loadTexture("Textures/Sky/Lagoon/blue.jpg");
		Texture down = assetManager.loadTexture("Textures/Sky/Lagoon/blue.jpg");

    Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down);
	rootNode.attachChild(sky);
    }

    private void createTerrain() {
        matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
        matRock.setBoolean("useTriPlanarMapping", false);
        matRock.setBoolean("WardIso", true);
        matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
        Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/island512.png");
        Texture grass = assetManager.loadTexture("Textures/Terrain/splat/snow.jpg");
        grass.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap", grass);
        matRock.setFloat("DiffuseMap_0_scale", 64);
        Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
        dirt.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap_1", dirt);
        matRock.setFloat("DiffuseMap_1_scale", 16);
        Texture rock = assetManager.loadTexture("Textures/Terrain/splat/sand.jpg");
        rock.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap_2", rock);
        matRock.setFloat("DiffuseMap_2_scale", 128);
        Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/normal.jpg");
        normalMap0.setWrap(WrapMode.Repeat);
        Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/normal.png");
        normalMap1.setWrap(WrapMode.Repeat);
        Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/normal.png");
        normalMap2.setWrap(WrapMode.Repeat);
        matRock.setTexture("NormalMap", normalMap0);
        matRock.setTexture("NormalMap_1", normalMap2);
        matRock.setTexture("NormalMap_2", normalMap2);

        AbstractHeightMap heightmap = null;
        try {
            heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f);
            heightmap.load();

        } catch (Exception e) {
            e.printStackTrace();
        }

        terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
        List<Camera> cameras = new ArrayList<Camera>();
        cameras.add(getCamera());
        TerrainLodControl control = new TerrainLodControl(terrain, cameras);
        terrain.addControl(control);
        terrain.setMaterial(matRock);
        terrain.setLocalScale(new Vector3f(2, 2, 2));

        terrainPhysicsNode = new RigidBodyControl(CollisionShapeFactory.createMeshShape(terrain), 0);
        terrain.addControl(terrainPhysicsNode);
        rootNode.attachChild(terrain);
        getPhysicsSpace().add(terrainPhysicsNode);
    }

    private void createCharacter() {
        CapsuleCollisionShape capsule = new CapsuleCollisionShape(1f, 4f);
        character = new CharacterControl(capsule, 0.01f);
//		character.setJumpSpeed(20);
//		character.setFallSpeed(35);
//		character.setGravity(30);		
        model = (Node) assetManager.loadModel("Models/erika/erika.j3o");
        model.setLocalScale(3.5f);
        model.addControl(character);
        character.setPhysicsLocation(new Vector3f(-140, 40, -10));
        rootNode.attachChild(model);
        getPhysicsSpace().add(character);
    }

    private void setupChaseCamera() {
        flyCam.setEnabled(false);
        chaseCam = new ChaseCamera(cam, model, inputManager);
    }

    private void setupAnimationController() {
        
    model.depthFirstTraversal(new SceneGraphVisitorAdapter() {
        @Override
        public void visit(Node node) {
            if (node.getControl(AnimControl.class) != null) {
                animationControl = node.getControl(AnimControl.class);
                animationControl.addListener(new AnimEventListener() {
                    @Override
                    public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {

                    }

                    @Override
                    public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
                        
                    }
                });

                animationChannel = animationControl.createChannel();

            }
        }
    });
    
            if (animationControl == null) {
            LOG.log(Level.SEVERE, "No AnimControl {0}", model);
            throw new RuntimeException();
        }
        
        
//        animationControl = model.getControl(AnimControl.class);
//        animationControl.addListener(this);
//        animationChannel = animationControl.createChannel();
//        shootingChannel = animationControl.createChannel();
//        shootingChannel.addBone(animationControl.getSkeleton().getBone("uparm.right"));
//       shootingChannel.addBone(animationControl.getSkeleton().getBone("arm.right"));
//        shootingChannel.addBone(animationControl.getSkeleton().getBone("hand.right"));
    }

    @Override
    public void simpleUpdate(float tpf) {
        Vector3f camDir = cam.getDirection().clone().multLocal(0.1f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.1f);
        camDir.y = 0;
        camLeft.y = 0;
        walkDirection.set(0,0,0);
        if (left) {
            walkDirection.addLocal(camLeft);
        }
        if (right) {
            walkDirection.addLocal(camLeft.negate());
        }
        if (up) {
            walkDirection.addLocal(camDir);
        }
        if (down) {
            walkDirection.addLocal(camDir.negate());
        }
        if (!character.onGround()) {
            airTime = airTime + tpf;
        } else {
            airTime = 0;
        }
        if (walkDirection.length() == 0) {
            if (!"idle".equals(animationChannel.getAnimationName())) {
                animationChannel.setAnim("idle", 1f);
            }
        } else {
            character.setViewDirection(walkDirection);
            if (airTime > .3f) {
                if (!"idle".equals(animationChannel.getAnimationName())) {
                    animationChannel.setAnim("idle");
                }
            } else if (!"Walk".equals(animationChannel.getAnimationName())) {
                animationChannel.setAnim("walk", 1f);
            }
        }
        character.setWalkDirection(walkDirection);
    }

    public void onAction(String binding, boolean value, float tpf) {
        if (binding.equals("CharLeft")) {
            if (value) {
                left = true;
            } else {
                left = false;
            }
        } else if (binding.equals("CharRight")) {
            if (value) {
                right = true;
            } else {
                right = false;
            }
        } else if (binding.equals("CharUp")) {
            if (value) {
                up = true;
            } else {
                up = false;
            }
        } else if (binding.equals("CharDown")) {
            if (value) {
                down = true;
            } else {
                down = false;
            }
        } else if (binding.equals("CharSpace")) {
            character.jump();
//        } else if (binding.equals("CharShoot") && !value) {
//            bulletControl();
        }
    }

    @Override
    public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
//        if (channel == animationChannel) {
//            channel.setAnim("idle");
//        }
    }

    @Override
    public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {

    }


}

I can’t figure out what happents.

1 Like

https://jmonkeyengine.github.io/wiki/jme3/beginner/hello_animation.html#responding-to-animation-events

1 Like

Ridiculous mistake. The “W” should be “w”. Now, one problem last.

1 Like

To make my character model not flying like in the picture above, i need to make on Blender the feet below the ground. about belly deep. For short I need to adjust it so the feed not below the ground or fly too high above the ground. i think. I don’t know why it happens.

Edit: Probably I can adjust the model by code. I looked to doc but still can’t find out how to do that.

1 Like

Its flying like that because the models origin and root bone origin are not located at the base of the models feet.

https://jmonkeyengine.github.io/wiki/jme3/external/blender.html#model-checklist

You can alternatively create a container type node to hold everything as is done here.

In this example, the spatials origin is at center which means it is sunk into the floor. Its local translation is set higher according to its world bounds and added to a node. The charNode is what is used to move the spatial.

https://jmonkeyengine.github.io/wiki/jme3/beginner/hello_node.html#what-is-a-pivot-node

2 Likes