[SOLVED] Camera not in sync with player

The camera is not completely in sync with the player so when i move it looks like the player is jittering until i stop and they catch up with each other. I’m using bettercharactercontroller and the default cam. I tried just attaching the camera to a camera node or to a node but in the case of the regular node, it can’t be attached and in the case of the camera node, i can’t look around. Like I said, what i have works, it just seems like the player moves in playerControl.setWalkDirection then the camera moves in cam.setLocation and that time inbetween causes very noticeable stutter. I’ve tried interpolation, but it still doesn’t give me what i want. i want the camera to move perfectly in sync with the player. How it should work: player controls location of camera and camera controls rotation of player.

My setup is loosly based on the HelloCollision way of doing things

in init:

    playerSpatial = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
    betterPlayer = (Node) playerSpatial;
    playerNode = new Node();
    playerNode.attachChild(betterPlayer); 
    betterPlayer.move(0, 1f, 0);
    betterPlayer.setLocalScale(0.03f);
    playerControl = new BetterCharacterControl(2.5f, 6f, 100f);
    playerNode.addControl(playerControl);
    playerControl.setJumpForce(new Vector3f(0, 2500f, 0));
    playerControl.warp(new Vector3f(0, 10, 10)); 
    bulletAppState.getPhysicsSpace().add(playerControl);
    bulletAppState.getPhysicsSpace().addAll(playerNode);
    playerControl.setGravity(new Vector3f(0, -20f, 0));
    cameraNode = new Node();
    playerNode.attachChild(cameraNode);
    cameraNode.setLocalTranslation(0, 6.5f, -1);

in update:

    playerControl.setViewDirection(cam.getDirection().negate());
    camDir.set(cam.getDirection()).multLocal(3000f);
    camLeft.set(cam.getLeft()).multLocal(3000f);
    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());
    }
    walkDirection.y = 0;
    walkDirection = walkDirection.normalizeLocal().multLocal(30);
    playerControl.setWalkDirection(walkDirection);
    cam.setLocation(cameraNode.getLocalTranslation());

In what update?

in simpleupdate

That’s way too early. simpleUpdate() runs before everything. So the physics hasn’t even updated the character control yet.

You need to make sure to synch the camera position as late as possible. In an app state, I’d say do it in prerender(). I don’t remember if SimpleApplication has the same thing or what it’s name is but you should be using app states anyway.

how do i know what to do in simpleupdate and what to do in app states?

If you want your game to be just one giant class file then put all 9,000,000 lines in simpleUpdate(). If you want to organize your game into separate classes then don’t put anything in simpleUpdate(). (None of my games have anything in simpleUpdate() and only very few things in simpleInit()).

…but to solve your current problem, you only need to make sure to update the camera in prerender. You can either make an app state or look at the javadoc for SimpleApplication to find out what its version is… just in case you are still wanting to put all of your game code into one giant class.

I was creating a playercharacter object in init and had an updatePlayerCharacter(tpf,cam); inside of simpleUpdate that would update the playercharacter each loop to avoid having everything in simple update. i’m going to have to take a closer look at appstates because they seem pretty complicated.

App states are just way of moving functionality into modular classes. So you could have an app state the just updates a camera from a character control and then enable/disable it at runtime.

App states are just extending the main application through composition instead of inheritance. (One should always prefer composition over inheritance.) At has the added benefits that you can make code reusable and you can add/remove it or enable/disable it depending on the game state.

For example, a lot of games don’t even attach the main game logic app states until the user has worked through a UI menu.

Edit: and since you seem reluctant to look at the javadoc, I did it for you. In SimpleApplication you can override simpleRender():
https://javadoc.jmonkeyengine.org/v3.x/com/jme3/app/SimpleApplication.html#simpleRender-com.jme3.renderer.RenderManager-

So is there any documentation on what kinds of things should go in render vs prerender vs postrender vs update vs simpleupdate? It seems like there are a lot of loops and no way of telling what kinds of items should go in which loop.

There is only one loop. And things are called in a certain order.

update, render, postrender.