Better Character Control doesn't move Node

Alright, so after taking a quick break from my voxel world I’ve got back to it, and it’s going pretty good so far.

Right now I’m trying to convert my code that uses CharacterControl to use the BetterCharacterControl, and the only issue I’m having so far is getting it to move a node…
Here is the code I’m using…

[java]playerNode = new Node();

player = new BetterCharacterControl(.9f, 1.9f, 1f);
player.setJumpForce(new Vector3f(0, 0, 0));
player.setGravity(new Vector3f(0, -10, 0));

playerNode.addControl(player);
app.getStateManager().getState(BulletAppState.class).getPhysicsSpace().add(player);

playerNode.setLocalTranslation(new Vector3f(2, 35, 2));[/java]

Ultimately what I’m doing with it is moving the camera based on the node’s location, however the node isn’t moving, so neither is the camera…

did you try using player.setPhysicsLocation()?

It’s using the BetterCharacterControl, it doesn’t have that method… (Actually it does, but it’s protected… and I would make an class that extends it, but I don’t think it was meant to be done that way, and will cause issues…)

what happens when you try
[java]player.warp(newLocation);[/java]

Also, are you using something like
[java]player.setWalkingDirection(direction);[/java]
to move the character?
Otherwise it won’t move for sure :wink:

@m41q said: what happens when you try [java]player.warp(newLocation);[/java]

When I do that, the node is always at 0,0,0…

Also, are you using something like [java]player.setWalkingDirection(direction);[/java] to move the character? Otherwise it won't move for sure :wink:

Yes, I am calling it in an update loop…

I think hes saying that setWalkDirection() overrides warp() because they both end up calling the same internal function.

Kind of like how spatial.move() is an alias for spatial.setLocalTranslation(). You should probably try a fresh project and try your code out. I just set up the same sort of thing and didn’t have an issue.

Yeah, this behavior is weird…
I recommend testing it on a fresh project as well.
Maybe you have some code setting the node to (0,0,0) somewhere hidden…
I use BetterCharacterControl all the time and it works fine.

Also when you have a little, fresh project, you can easily send us all of the source code.

btw this is the test project i made just now

[java]package jme3test;

import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;

/**
*

  • @author Daniel Strong aka icamefromspace
    */
    public class BetterCharacterTest extends SimpleApplication {

    public static void main(String args) {
    BetterCharacterTest test = new BetterCharacterTest();
    test.start();
    }

    private Node playerNode;

    @Override
    public void simpleInitApp() {
    stateManager.attach(new BulletAppState());
    playerNode = new Node();

         BetterCharacterControl player = new BetterCharacterControl(.9f, 1.9f, 1f);
         player.setJumpForce(new Vector3f(0, 0, 0));
         player.setGravity(new Vector3f(0, -10, 0));
    
         playerNode.addControl(player);
         getStateManager().getState(BulletAppState.class).getPhysicsSpace().add(player);
    
    
         rootNode.attachChild(playerNode);
    
         player.warp(new Vector3f(2, 35, 2));
    

    }

    @Override
    public void simpleUpdate(float tpf) {
    super.simpleUpdate(tpf);
    System.out.println(playerNode.getLocalTranslation());
    }

}
[/java]

(0.0, 0.0, 0.0) (2.0, 35.0, 2.0) (2.0, 34.97275, 2.0) (2.0, 34.9019, 2.0) (2.0, 34.877377, 2.0) (2.0, 34.85013, 2.0) (2.0, 34.820152, 2.0) (2.0, 34.787453, 2.0) (2.0, 34.75203, 2.0) (2.0, 34.71388, 2.0) (2.0, 34.673004, 2.0) (2.0, 34.629406, 2.0) (2.0, 34.58308, 2.0)

(hes falling through space)

Well, I’m glad to announce to you…
…everything works :wink:

The player spawns and gets teleported to (2, 35, 2) and starts falling.
If you wanna move the node, you need to add something like
player.setWalkingDirection(new Vector3f(1,0,0);
to the simpleUpdate method.

If you wanna move the player through keys, you need to add the mapping to the input manager, calculate the appropiate walking direction and apply it.

Alright, I’ll search for setting the node location somewhere…

Alright, here is the code I’m using…

The movement booleans are declared to be public, and are modified by a separate appstate I have managing keystrokes…

[java]
package EntityFrame;

import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Node;

/**

  • This is an object that manages the a player
    */
    public class Player
    {
    // Our boolean variables for movement
    public boolean forward = false, backward = false, lStrafe = false, rStrafe = false;
    // Temporary vectors for moving the player
    private Vector3f camDir;
    private Vector3f camLeft;
    private Vector3f walkDir;
    private Vector3f loc;
    // The camera that this player can see
    private Camera cam;
    // The actual player object
    private BetterCharacterControl player;
    // The node that manages the player
    private Node playerNode;

/**

  • This is the constructor, it is in charge of initializing default values
  • @param cam :: The camera that this player uses
  • @param Bas :: BulletAppState, used for incorporating physics
    */
    public Player(Camera cam, BulletAppState Bas)
    {
    // Initialize vectors now to save time later
    camDir = new Vector3f(0,0,0);
    camLeft = new Vector3f(0,0,0);
    walkDir = new Vector3f(0,0,0);
    loc = new Vector3f(0,0,0);
// Store the given camera
this.cam = cam;

// Setup global character properties
player = new BetterCharacterControl(.9f, 1.9f, 1f);
player.setJumpForce(new Vector3f(0, 0, 0));
player.setGravity(new Vector3f(0, -10, 0));

// Attach the player and give it physics
playerNode = new Node("Player Node");
playerNode.addControl(player);
Bas.getPhysicsSpace().add(player);

// Initialize to default location
player.warp(new Vector3f(2, 35, 2));

}

/**

  • This is the update sequence, it
  • Manages the walking behavior
  • @param tpf :: The time per frame
    */
    public void update(float tpf)
    {
    // Establish camera directions
    camDir.set(cam.getDirection().multLocal(0.125f));
    camLeft.set(cam.getLeft().multLocal(0.08f));
// Reset walk direction, and fix a camera direction issue
camDir.y = 0;
walkDir.set(0,0,0);

// Set the walk direction
if(forward)
{walkDir.addLocal(camDir);}
if(backward)
{walkDir.addLocal(camDir.negate());}
if(lStrafe)
{walkDir.addLocal(camLeft);}
if(rStrafe)
{walkDir.addLocal(camLeft.negate());}

// Walk
player.setWalkDirection(walkDir);

// Setup the camera to match the walk direction
loc.set(playerNode.getLocalTranslation());
loc.y += 1.5;
cam.setLocation(loc);

System.out.println(playerNode.getLocalTranslation());

}

/**

  • Makes the player jump
    */
    public void jump()
    {player.jump();}
    }
    [/java]
@chessmaster942 said: Alright, here is the code I'm using..

Ok, so I tested it out and I got the idea that maaaybee it’s a good idea to attach the playerNode to the rootNode :lol:

It worked for me, let me know if the issue is fixed.

I’m not in front of it anymore… but if that’s the issue… :explode:

The bad news :
Yup, it was another idiot mistake on my part… :facepalm:

The good news :
I now know why I was wrong, and won’t be doing that again. :stuck_out_tongue_winking_eye:

Thanks for all the help!

1 Like
@chessmaster942 said: I'm not in front of it anymore... but if that's the issue... :explode:
@chessmaster942 said: The bad news : Yup, it was another idiot mistake on my part.. :facepalm:

The good news :
I now know why I was wrong, and won’t be doing that again. :stuck_out_tongue_winking_eye:

Thanks for all the help!

I just loved the perfect use of the emoticons… just great. :slight_smile:

1 Like