1

I'm trying to render a model for the main character but no matter which vector or rotation I put in he is hanging in the air, all I see are his feet and they are turned the wrong way:

enter image description here

When I press walk, the green person moves but backwards and I couldn't fix it with a rotation around the Y:

character = new CharacterControl(capsule, 0.01f);
    model = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
     model.setLocalScale(0.15f);

     Quaternion yaw90 = new Quaternion();
     Quaternion roll90 = new Quaternion();
     Quaternion pitch90 = new Quaternion();
     yaw90.fromAngles(1, 0, 0);
     roll90.fromAngles(0, 1, 0);
     pitch90.fromAngles(0, 0, 1);
     model.rotate(roll90);

     model.addControl(character);
    character.setPhysicsLocation(new Vector3f(-140, 15, -10));
    rootNode.attachChild(model);

The complete code for the entire scene is

package adventure;

import java.applet.Applet;
import com.jme3.math.Quaternion;
import com.jme3.math.FastMath;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.TextArea;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import com.jme3.material.RenderState.FaceCullMode;
import javax.swing.JFrame;
import javax.swing.JPanel;

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.asset.BlenderKey;
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.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
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;

public class MountainWorld extends SimpleApplication implements ActionListener,
        PhysicsCollisionListener, AnimEventListener, Playable {
    private static World world;
    private static Person person;
    private static Player dplayer;
    private static TextArea textarea;
    private BulletAppState bulletAppState;
    private AnimChannel channel;
    private AnimControl control;
    // 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;
    // bullet
    Sphere bullet;
    SphereCollisionShape bulletCollisionShape;
    // explosion
    ParticleEmitter effect;
    // brick wall
    Box brick;
    float bLength = 0.8f;
    float bWidth = 0.4f;
    float bHeight = 0.4f;
    FilterPostProcessor fpp;

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                AppSettings settings = new AppSettings(true);
                settings.setWidth(850);
                settings.setHeight(440);

                MountainWorld canvasApplication = new MountainWorld();
                canvasApplication.setSettings(settings);
                canvasApplication.createCanvas(); // create canvas!
                JmeCanvasContext ctx = (JmeCanvasContext) canvasApplication
                        .getContext();
                ctx.setSystemListener(canvasApplication);
                Dimension dim = new Dimension(640, 480);
                ctx.getCanvas().setPreferredSize(dim);

                JFrame window = new JFrame("Mountain World");
                window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JPanel panel = new JPanel(new BorderLayout()); // a panel
                world = new DungeonWorld(canvasApplication);
                person = new Person(world, "You", null);
                dplayer = new Player(world, person);
                Commands commands = new Commands(person);
                textarea = new TextArea("", 10, 60,
                        TextArea.SCROLLBARS_VERTICAL_ONLY);
                textarea.append("You are in a mountain. The trolls live here.\n");
                textarea.setEditable(false);
                panel.add("West", ctx.getCanvas());
                panel.add("East", commands);
                panel.add("South", textarea);
                window.add(panel);
                window.pack();
                window.setVisible(true);
                canvasApplication.startCanvas();

            }
        });
    }

    @Override
    public void simpleInitApp() {
        bulletAppState = new BulletAppState();
        bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
        stateManager.attach(bulletAppState);
        setupKeys();
        prepareBullet();
        prepareEffect();
        createLight();
        createSky();
        createTerrain();
        createWall();
        createCharacters();



        setupChaseCamera();
        setupAnimationController();
        setupFilter();
    }

    private void setupFilter() {
        FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
        BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects);
        fpp.addFilter(bloom);
        viewPort.addProcessor(fpp);
    }

    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_RETURN));
        inputManager
                .addMapping("CharShoot", new KeyTrigger(KeyInput.KEY_SPACE));
        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 createWall() {
        float xOff = -144;
        float zOff = -40;
        float startpt = bLength / 4 - xOff;
        float height = 6.1f;
        brick = new Box(Vector3f.ZERO, bLength, bHeight, bWidth);
        brick.scaleTextureCoordinates(new Vector2f(1f, .5f));
        for (int j = 0; j < 15; j++) {
            for (int i = 0; i < 4; i++) {
                Vector3f vt = new Vector3f(i * bLength * 2 + startpt, bHeight
                        + height, zOff);
                addBrick(vt);
            }
            startpt = -startpt;
            height += 1.01f * bHeight;
        }
    }

    private void addBrick(Vector3f ori) {
        Geometry reBoxg = new Geometry("brick", brick);
        reBoxg.setMaterial(matBullet);
        reBoxg.setLocalTranslation(ori);
        reBoxg.addControl(new RigidBodyControl(1.5f));
        reBoxg.setShadowMode(ShadowMode.CastAndReceive);
        this.rootNode.attachChild(reBoxg);
        this.getPhysicsSpace().add(reBoxg);
    }

    private void prepareBullet() {
        bullet = new Sphere(32, 32, 0.4f, true, false);
        bullet.setTextureMode(TextureMode.Projected);
        bulletCollisionShape = new SphereCollisionShape(0.4f);
        matBullet = new Material(getAssetManager(),
                "Common/MatDefs/Misc/Unshaded.j3md");
        matBullet.setColor("Color", ColorRGBA.Green);
        // matBullet.setColor("m_GlowColor", ColorRGBA.Green);
        getPhysicsSpace().addCollisionListener(this);
    }

    private void prepareEffect() {
        int COUNT_FACTOR = 1;
        float COUNT_FACTOR_F = 1f;
        effect = new ParticleEmitter("Flame", Type.Triangle, 32 * COUNT_FACTOR);
        effect.setSelectRandomImage(true);
        effect.setStartColor(new ColorRGBA(1f, 0.4f, 0.05f,
                (float) (1f / COUNT_FACTOR_F)));
        effect.setEndColor(new ColorRGBA(.4f, .22f, .12f, 0f));
        effect.setStartSize(1.3f);
        effect.setEndSize(2f);
        effect.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));
        effect.setParticlesPerSec(0);
        effect.setGravity(0, -5, 0);
        effect.setLowLife(.4f);
        effect.setHighLife(.5f);
        effect.setInitialVelocity(new Vector3f(0, 7, 0));
        effect.setVelocityVariation(1f);
        effect.setImagesX(2);
        effect.setImagesY(2);
        Material mat = new Material(assetManager,
                "Common/MatDefs/Misc/Particle.j3md");
        mat.setTexture("Texture",
                assetManager.loadTexture("Effects/Explosion/flame.png"));
        effect.setMaterial(mat);
        // effect.setLocalScale(100);
        rootNode.attachChild(effect);
    }

    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() {
        rootNode.attachChild(SkyFactory.createSky(assetManager,
                "Textures/Sky/Bright/BrightSky.dds", false));
    }

    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/mountains512.png");
        Texture grass = assetManager
                .loadTexture("Textures/Terrain/splat/grass.jpg");
        grass.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap", grass);
        matRock.setFloat("DiffuseMap_0_scale", 64);
        Texture dirt = assetManager
                .loadTexture("Textures/Terrain/splat/dirt.jpg");
        dirt.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap_1", dirt);
        matRock.setFloat("DiffuseMap_1_scale", 16);
        Texture rock = assetManager
                .loadTexture("Textures/Terrain/splat/road.jpg");
        rock.setWrap(WrapMode.Repeat);
        matRock.setTexture("DiffuseMap_2", rock);
        matRock.setFloat("DiffuseMap_2_scale", 128);
        Texture normalMap0 = assetManager
                .loadTexture("Textures/Terrain/splat/grass_normal.jpg");
        normalMap0.setWrap(WrapMode.Repeat);
        Texture normalMap1 = assetManager
                .loadTexture("Textures/Terrain/splat/dirt_normal.png");
        normalMap1.setWrap(WrapMode.Repeat);
        Texture normalMap2 = assetManager
                .loadTexture("Textures/Terrain/splat/road_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 createCharacters() {
        CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f);
        character = new CharacterControl(capsule, 0.01f);
        model = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
         model.setLocalScale(0.15f);

         Quaternion yaw90 = new Quaternion();
         Quaternion roll90 = new Quaternion();
         Quaternion pitch90 = new Quaternion();
         yaw90.fromAngles(1, 0, 0);
         roll90.fromAngles(0, 1, 0);
         pitch90.fromAngles(0, 0, 1);
         model.rotate(roll90);

         model.addControl(character);
        character.setPhysicsLocation(new Vector3f(-140, 15, -10));
        rootNode.attachChild(model);
        getPhysicsSpace().add(character);

        BlenderKey blenderKey = new BlenderKey(
                "objects/creatures/alien/alien.mesh.xml");

        Node alien = (Node) assetManager.loadModel(blenderKey);
        alien.setLocalTranslation(new Vector3f(-145, 15, -10));
        //Geometry geom=(Geometry)alien.getChild("myGeometry");
        //geom.getMaterial().getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);

        rootNode.attachChild(alien);



        BlenderKey blenderKey2 = new BlenderKey(
                "objects/creatures/spaceman/man.mesh.xml");

        Spatial man = (Spatial) assetManager.loadModel(blenderKey2);
        man.setLocalTranslation(new Vector3f(-140, 15, -10));

        rootNode.attachChild(man);

    }

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

    private void setupAnimationController() {
        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 (!"Idle1".equals(animationChannel.getAnimationName())) {
                animationChannel.setAnim("Idle1", 1f);
            }
        } else {
            character.setViewDirection(walkDirection);
            if (airTime > .3f) {
                if (!"stand".equals(animationChannel.getAnimationName())) {
                    animationChannel.setAnim("stand");
                }
            } 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();
        }
    }

    private void bulletControl() {
        shootingChannel.setAnim("Dodge", 0.1f);
        shootingChannel.setLoopMode(LoopMode.DontLoop);
        Geometry bulletg = new Geometry("bullet", bullet);
        bulletg.setMaterial(matBullet);
        bulletg.setShadowMode(ShadowMode.CastAndReceive);
        bulletg.setLocalTranslation(character.getPhysicsLocation().add(
                cam.getDirection().mult(5)));
        RigidBodyControl bulletControl = new BombControl(bulletCollisionShape,
                1);
        bulletControl.setCcdMotionThreshold(0.1f);
        bulletControl.setLinearVelocity(cam.getDirection().mult(80));
        bulletg.addControl(bulletControl);
        rootNode.attachChild(bulletg);
        getPhysicsSpace().add(bulletControl);
    }

    public void collision(PhysicsCollisionEvent event) {
        if (event.getObjectA() instanceof BombControl) {
            final Spatial node = event.getNodeA();
            effect.killAllParticles();
            effect.setLocalTranslation(node.getLocalTranslation());
            effect.emitAllParticles();
        } else if (event.getObjectB() instanceof BombControl) {
            final Spatial node = event.getNodeB();
            effect.killAllParticles();
            effect.setLocalTranslation(node.getLocalTranslation());
            effect.emitAllParticles();
        }
    }

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

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

    // Load an image from the net, making sure it has already been
    // loaded when the method returns
    public Image loadPicture(String imageName) {
        return null;
    }

    // Load and play a sound from /usr/local/hacks/sounds/

    public void playSound(String name) {
        URL u = null;

        try {
            u = new URL("file:" + "/usr/local/hacks/sounds/" + name + ".au");
        } catch (MalformedURLException e) {
        }

        AudioClip a = Applet.newAudioClip(u);
        a.play();
    }
}

I'm wondering how to render my green ninja with the back natural towards the camer an player being able to control the ninja and walk the ninja which now works but with wrong location (in the air) and I can't seem to adjust the position.

Any suggestions?

Update

The following code appears the improve the position of the green person:

private void createCharacters() {
    CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f);
    character = new CharacterControl(capsule, 0.01f);
    model = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
    model.setLocalScale(0.15f);

    model.addControl(character);
    character.setPhysicsLocation(new Vector3f(-140, 20, -9));
    character.setViewDirection(new Vector3f(1, 1, 1));
    rootNode.attachChild(model);
    getPhysicsSpace().add(character);

    BlenderKey blenderKey = new BlenderKey(
            "objects/creatures/alien/alien.mesh.xml");

    Node alien = (Node) assetManager.loadModel(blenderKey);
    alien.setLocalTranslation(new Vector3f(-145, 15, -10));     
    rootNode.attachChild(alien);

    BlenderKey blenderKey2 = new BlenderKey(
            "objects/creatures/spaceman/man.mesh.xml");

    Spatial man = (Spatial) assetManager.loadModel(blenderKey2);
    man.setLocalTranslation(new Vector3f(-140, 15, -10));

    rootNode.attachChild(man);

}

But walking still works somewhat like the opposite of what it should. But I'm glad that I at least could improve the scene so that the main character is rotated properly. I'll update with another screenshot and more details a.s.a.p.

Please answer or comment with any improvement suggestion.

Update

I could rotate the green person but will harmonize the models in blender also:

private void createCharacters() {
    CapsuleCollisionShape capsule = new CapsuleCollisionShape(3f, 4f);
    character = new CharacterControl(capsule, 0.01f);
    model = (Node) assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
    model.setLocalScale(0.15f);

    model.addControl(character);
    character.setPhysicsLocation(new Vector3f(-140, 20, -9));
    character.setViewDirection(new Vector3f(1, 1, 1));
    rootNode.attachChild(model);
    getPhysicsSpace().add(character);

    BlenderKey blenderKey = new BlenderKey(
            "objects/creatures/alien/alien.mesh.xml");

    Node alien = (Node) assetManager.loadModel(blenderKey);
    alien.setLocalTranslation(new Vector3f(-145, 15, -10));


    rootNode.attachChild(alien);



    BlenderKey blenderKey2 = new BlenderKey(
            "objects/creatures/spaceman/man.mesh.xml");

    Spatial man = (Spatial) assetManager.loadModel(blenderKey2);
    man.setLocalTranslation(new Vector3f(-140, 15, -10));

    rootNode.attachChild(man);

}

enter image description here

Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
  • 1
    It's not an answer for your question, but when you create more than one model for one application, make sure they are modeled in the same scale, facing the same direction, and their feet are at the same level in Blender - this will save you much, much work later. – kolenda Jul 31 '12 at 08:42
  • @kolenda Yes it answers how I improve the scene. I will learn more blender to harmonize the models. I'm really glad that you are here giving me this advice saving me a lot of time and research. I don't think I can edit the green person since it is builtin but I can adjust the alien, the spaceman and a troll. Then I hope to learn how I can make my own environment and more of a custom scene since I took this scene from an example and just switched the model for the main character because the green ninja has many builtin moves. – Niklas Rosencrantz Jul 31 '12 at 10:15

1 Answers1

2

when you "walk", does the green person actually walk backwards in the sense that his walking animation is even backwards? regardless, maybe it would be better to move the camera behind the guy? and it's odd how you CAN'T rotate the guy on the Y axis. Id try to get that working first, otherwise, who knows what could be wrong if your basic axis rotations don't work.

AlvinfromDiaspar
  • 6,611
  • 13
  • 75
  • 140
  • 1
    Also, is it ONLY the green person that is not working? All of the other characters behave properly? – AlvinfromDiaspar Jul 31 '12 at 04:55
  • Thank you for the investigation. I now managed the improve the rotation by adding a basic rotation and it seems to have worked. The animation is not backwards, when I try to walk forwards the feet walk forward but the character + camera move backwards. The other characters don't have animations, I just exported them from Blender and the green character is a builtin character that has several animation and would be suitable for diplaying in third person so I took code from a third person implementation (WalkingCharacter) and changed the walking model to the ninja (it used to be oto.mesh). – Niklas Rosencrantz Jul 31 '12 at 05:58
  • 1
    When you try to walk forward, is the green thing walk backward (moving away from you) or is the camera moving backwards (away from the green thing).... or is it both? – AlvinfromDiaspar Jul 31 '12 at 13:53
  • The green person and the camera stay together but it's like the green person does a moonwalk where the feet moves forward but the movement is backwards. It looks just like a "moonwalk" i.e. when I try to walk forward the animation plays forward but the movement is backwards. I will experiment more with this onwards, I do think it's solvable in near time. Thank you for all the help! – Niklas Rosencrantz Jul 31 '12 at 14:21