How to link camera w/ character movement? (CameraNode)

Hi all,

My goal is to have a character on some ground moving around with a walk animation.
Question 1: Do I have my camera set up properly?

Context/Question 1
Last night I used the Hello Collision and Follow a Character tutorials. At the bottom of collision there was a little section “simpler collision detection solutions without physics” so I used that example code https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-examples/src/main/java/jme3test/collision/TestTriangleCollision.java
I still don’t understand physics in j monkey very well but right now I am thinking all I really need is collision detection for boulders and walls and things like that so I tried out that simpler example. I combined that with CameraNode from the Camera/Follow a Character section. My character was sliding over the ground which was pretty cool and my camera was set in the right spot but when I moved the camera didn’t follow him and he would quite quickly just slide off the screen :expressionless: that’s no good-this will either be a very short video game or you really won’t know what’s going on.

In my analog listener section I just moved the camera node (heroNode) along with my model.

@Override
        public void onAnalog(String name, float value, float tpf) {
            if (name.equals("MoveRight")) {
                model.move(2 * tpf, 0, 0);
                                heroNode.move(2 * tpf, 0, 0);

My camera followed my guy but is this even a good idea? I felt like in the tutorial I was following my camera was supposed to follow along but it didn’t so I’m not sure if I’m missing something, if that is even an ok idea, or there is a much more efficient way to get the camera to follow along.

full code

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingVolume;
import com.jme3.collision.CollisionResults;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.math.Vector3f;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.CameraControl.ControlDirection;

public class TestTriangleCollision extends SimpleApplication {

    private Spatial terrain;

    private Spatial model;
    
    private Node heroNode;
    
      final private Vector3f direction = new Vector3f();
    

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

    @Override
    public void simpleInitApp() {
        // load model
        
          model = assetManager.loadModel("Models/test4.j3o");
        model.setLocalTranslation(0f, 0f, 0f);
        
           //create a node to attach the geometry and the camera node
           heroNode = new Node("heroNode");
           heroNode.attachChild(model);
                      rootNode.attachChild(heroNode);

            terrain = assetManager.loadModel("Scenes/ground4.j3o");
                rootNode.attachChild(terrain);
           
           CameraNode camNode = new CameraNode("CamNode",cam);
           camNode.setControlDir(ControlDirection.SpatialToCamera);
           heroNode.attachChild(camNode);
           camNode.setLocalTranslation(new Vector3f(0,5,-5));
           camNode.lookAt(heroNode.getLocalTranslation(), Vector3f.UNIT_Y);

               flyCam.setEnabled(false);
        // load a character from jme3-testdata
      
        
       


        // We must add a light to make the model visible
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f).normalizeLocal());
        model.addLight(sun);
        rootNode.attachChild(model);

        // Create input
        inputManager.addMapping("MoveRight", new KeyTrigger(KeyInput.KEY_L));
        inputManager.addMapping("MoveLeft", new KeyTrigger(KeyInput.KEY_J));
        inputManager.addMapping("MoveUp", new KeyTrigger(KeyInput.KEY_I));
        inputManager.addMapping("MoveDown", new KeyTrigger(KeyInput.KEY_K));

        inputManager.addListener(analogListener, new String[]{
                    "MoveRight", "MoveLeft", "MoveUp", "MoveDown"
                });
    }
    final private AnalogListener analogListener = new AnalogListener() {

         @Override
        public void onAnalog(String name, float value, float tpf) {
            if (name.equals("MoveRight")) {
                model.move(2 * tpf, 0, 0);
                                heroNode.move(2 * tpf, 0, 0);

            }

            if (name.equals("MoveLeft")) {
                model.move(-2 * tpf, 0, 0);
                                heroNode.move(-2 * tpf, 0, 0);

            }

            if (name.equals("MoveUp")) {
                model.move(0, 0,2*tpf);
                                heroNode.move(0, 0,2*tpf);

            }

            if (name.equals("MoveDown")) {
                model.move(0,0, -2*tpf);
                                heroNode.move(0,0, -2*tpf);

            }
        }
    };

    
}

Have you tried the built in ChaseCamera :

1 Like

I didn’t - basing my decision solely off of

camera node
Camera follows immediately, flies at same speed as target.

chasecam
Camera moves smoothly and accelerates and decelerates, flies more slowly than the target and catches up.

I didn’t think chase cam was what I wanted but I will definitely give it a try now and see what happens. thank you for the idea Pavl!