Hi,
I am having quite a few problem with my player movement and rotation, but first the code:
[java]package mygame;
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
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.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
public class Main extends SimpleApplication implements ActionListener, AnimEventListener {
public static void main(String[] args) {
Main app = new Main();
app.start();
}
private Spatial gameLevel;
private Spatial player;
private Quaternion myQuaternion = new Quaternion(0f, 1f, 0f, 1f);
private BulletAppState bulletAppState;
private BetterCharacterControl playerControl;
private ChaseCamera chaseCam;
private AnimChannel animChannel;
private AnimControl animControl;
private boolean left,right, up, down, jump, sprint, placeholder;
private Vector3f walkDirection = new Vector3f(0,0,0);
private float airTime = 0;
private Vector3f viewDirection = new Vector3f();
Node playerNode;
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
flyCam.setEnabled(false);
mouseInput.setCursorVisible(false);
initSunLight();
initAmbientLight();
initScene();
initPlayer();
initPlayerPhysics();
initChaseCam();
initControls();
}
@Override
public void simpleUpdate(float tpf) {
walkDirection.set(0,0,0);
if (up && !down){
walkDirection.addLocal(1f, 0f, 0f);
}
if (down && !up && !sprint){ walkDirection.addLocal(-0.5f, 0f, 0f);
}
if (up && sprint){
walkDirection.addLocal(2f, 0f, 0f);
}
if (left){
playerControl.getViewDirection();
playerControl.setViewDirection(myQuaternion.mult(Vector3f.UNIT_Z));
}
if (right){
playerControl.setViewDirection(myQuaternion.mult(Vector3f.UNIT_Z.negate()));
}
if (jump){
playerControl.jump();
}
/* if (!playerControl.isOnGround()) {
airTime += tpf;
} else {
airTime = 0;
}*/
playerControl.setWalkDirection(walkDirection.multLocal(5f));
}
@Override
public void simpleRender(RenderManager rm) {
}
private void initSunLight(){
DirectionalLight sun = new DirectionalLight();
sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());
sun.setColor(ColorRGBA.White);
rootNode.addLight(sun);
}
private void initAmbientLight(){
/** A white ambient light source. */
AmbientLight ambient = new AmbientLight();
ambient.setColor(ColorRGBA.White.mult(1.3f));
rootNode.addLight(ambient);
}
private void initScene(){
gameLevel = assetManager.loadModel("Scenes/Scene.j3o");
gameLevel.setLocalTranslation(0, -1, 0);
gameLevel.addControl(new RigidBodyControl(0f));
// 0 stands for the weight of the object (how fast it falls to the ground)
rootNode.attachChild(gameLevel);
bulletAppState.getPhysicsSpace().addAll(gameLevel);
}
private void initPlayer(){
//create player
player = assetManager.loadModel("Models/turtle/TURTLE_body.mesh.xml");
player.setMaterial(assetManager.loadMaterial("Materials/turtle.j3m"));
player.scale(1f);
player.rotate(0, FastMath.PI / 2 , 0);
playerNode = new Node();
playerNode.attachChild(player);
animControl = player.getControl(AnimControl.class);
animControl.addListener(this);
animChannel = animControl.createChannel();
animChannel.setAnim("idle");
animChannel.setSpeed(1f);
}
private void initPlayerPhysics(){
//Create Controls
playerControl = new BetterCharacterControl(0.26f, 0.5f, 20f); //contruct character collsion shape and weight
playerNode.addControl(playerControl); //attach Control to playerNode crated above
playerControl.setJumpForce(new Vector3f(0, 20f, 0));
playerControl.setGravity(new Vector3f(0, -10f, 0));
playerControl.warp(new Vector3f(0, 10, 10));
bulletAppState.getPhysicsSpace().add(playerControl);
bulletAppState.getPhysicsSpace().addAll(playerNode);
rootNode.attachChild(playerNode);
}
private void initChaseCam(){
chaseCam = new ChaseCamera(cam, player, inputManager);
chaseCam.setSmoothMotion(true);
chaseCam.setTrailingEnabled(true);
chaseCam.setMinDistance(5f);
chaseCam.getHorizontalRotation();
}
private void initControls(){
inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("CharForward", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("CharBackward", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("CharJump", new KeyTrigger (KeyInput.KEY_SPACE));
inputManager.addMapping("CharSprint", new KeyTrigger (KeyInput.KEY_LSHIFT));
inputManager.addListener(this, "CharLeft", "CharRight");
inputManager.addListener(this, "CharForward", "CharBackward");
inputManager.addListener(this, "CharJump");
inputManager.addListener(this, "CharSprint");
}
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("CharLeft")) {
left = isPressed;
} if (name.equals("CharRight")) {
right = isPressed;
} if (name.equals("CharForward")) {
up = isPressed;
} if (name.equals("CharBackward")) {
down = isPressed;
} if (name.equals("CharJump")){
jump = isPressed;
} if (name.equals("CharSprint")){
sprint = isPressed;
}
}
public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
}
public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
//unused
}
}
[/java]
The problems:
Rotation problem:
When i press A or D the player “snaps”, or instantly rotates 90°, basically instantly looks to his left or to his right, but only the left or right, from his origin position. So pressing A two times has o effect.
Desired Result:
A continuous rotation which is dependant on the current viewDirection.
Movement Problem:
After the player rotated and I press W he still moves in the same direction.
I would like the player always to move in the viewDirection.
Terrain Adjustement Problem:
The player is a turtle (you have to imagine it basically like a Car). However, the player does not adjust to the terrain:
I would like the turtle to move up hills like this. (This should naturally apply to all rotations)
I hope all my problems are clear, and thank you a ton in advance for any hep.