I know that this topic has been dicussed a lot, but I’ve been looking for hours now to solve my problem but I can’t find the solution. I simply want to attach a gun and a flashlight to my first person game. This is the code I’m currently using:
[java]package mygame;
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.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.SpotLight;
import com.jme3.math.FastMath;
import com.jme3.math.Transform;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
/**
-
test
-
@author normenhansen
*/
public class Main extends SimpleApplication implements ActionListener {private BulletAppState bulletAppState;
private RigidBodyControl terrainControl;
private Node player;
private BetterCharacterControl playerControl;private Vector3f walkDirection = new Vector3f(0.0f, 0.0f, 0.0f);
private boolean left,right,front,back;
private boolean zoomEnabled = true;
private SpotLight flashlight;
private Spatial flashlightModel;private boolean flashlight_on = true;
private Spatial gun;
private Node modelNode;
public static void main(String[] args) {
Main app = new Main();
app.start();
}@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);initTerrain(); initHUD(); initPlayer(); initGunAndFlashlight(); initLight(); initKeys(); initWall();
}
private void initTerrain() {
Spatial terrain = assetManager.loadModel(“Scenes/Terrain.j3o”);
terrainControl = new RigidBodyControl(0.0f);
terrain.addControl(terrainControl);
bulletAppState.getPhysicsSpace().add(terrainControl);
rootNode.attachChild(terrain);
}private void initHUD() {
setDisplayStatView(false);
setDisplayFps(false);
BitmapText ch = new BitmapText(guiFont, false);
ch.setSize(guiFont.getCharSet().getRenderedSize() * 3);
ch.setText("+"); // fake crosshairs
ch.setLocalTranslation( // center
settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
guiNode.attachChild(ch);
}private void initPlayer() {
player = new Node(“player”);
playerControl = new BetterCharacterControl(0.5f, 1.8f, 80f);
playerControl.setApplyPhysicsLocal(true);
playerControl.setSpatial(player);
player.addControl(playerControl);
bulletAppState.getPhysicsSpace().add(playerControl);
playerControl.warp(new Vector3f(58f, 6f, 0.0f));
rootNode.attachChild(player);
playerControl.setGravity(new Vector3f(0f, -50, 0f));
}private void initGunAndFlashlight() {
modelNode = new Node(); gun = assetManager.loadModel("Models/m16.j3o"); gun.rotate(0f, 270 * FastMath.DEG_TO_RAD, 0f); gun.scale(0.2f); gun.setLocalTranslation(new Vector3f(0.6f, 0.8f, -1.3f)); //gun: 0.5f, 1.3f, -1.6f; m16:0.6f, 0.8f, -1.3f; shotgun: 0.4f, 1.2f, -1f; sniper:0.8f, 0.4f, -2.3f modelNode.attachChild(gun); flashlightModel = assetManager.loadModel("Models/flashlight.j3o"); flashlightModel.scale(0.1f); flashlightModel.setLocalTranslation(new Vector3f(-0.5f, 1.3f, -1.3f)); modelNode.attachChild(flashlightModel); player.attachChild(modelNode);
}
private void initLight() {
flashlight = new SpotLight();
flashlight.setSpotRange(45);
flashlight.setSpotOuterAngle(30 * FastMath.DEG_TO_RAD);
flashlight.setSpotInnerAngle(20 * FastMath.DEG_TO_RAD);
flashlight.setDirection(cam.getDirection());
flashlight.setPosition(cam.getLocation());
rootNode.addLight(flashlight);
}private void initWall() {
}
public void initKeys() {
inputManager.addMapping(“Left”, new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping(“Right”, new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping(“Front”, new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping(“Back”, new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping(“Jump”, new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping(“Flashlight”, new KeyTrigger(KeyInput.KEY_F));inputManager.addListener(this, "Left"); inputManager.addListener(this, "Right"); inputManager.addListener(this, "Front"); inputManager.addListener(this, "Back"); inputManager.addListener(this, "Jump"); inputManager.addListener(this, "Flashlight");
}
@Override
public void simpleUpdate(float tpf) {
if(zoomEnabled) {
inputManager.deleteMapping(“FLYCAM_ZoomIn”);
inputManager.deleteMapping(“FLYCAM_ZoomOut”);
zoomEnabled = false;
}Vector3f camDir = cam.getDirection().mult(10f); Vector3f camLeft = cam.getLeft().mult(5f); walkDirection.set(0.0f, 0.0f, 0.0f); if(left) { walkDirection.addLocal(camLeft); } if(right) { walkDirection.addLocal(camLeft.negate()); } if(front) { walkDirection.addLocal(camDir); } if(back) { camDir = cam.getDirection().mult(2.5f); walkDirection.addLocal(camDir.negate()); } walkDirection.setY(0.0f); playerControl.setWalkDirection(walkDirection); cam.setLocation(player.getLocalTranslation().add(0,1.8f,0)); player.setLocalRotation(cam.getRotation()); //modelNode.setLocalRotation(cam.getRotation()); flashlight.setDirection(cam.getDirection()); flashlight.setPosition(cam.getLocation());
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}public void onAction(String name, boolean isPressed, float tpf) {
if(name.equals(“Left”)) {
left = isPressed;
} else if(name.equals(“Right”)) {
right = isPressed;
} else if(name.equals(“Front”)) {
front = isPressed;
} else if(name.equals(“Back”)) {
back = isPressed;
} else if(name.equals(“Jump”)) {
playerControl.jump();
} else if(name.equals(“Flashlight”)) {
if(isPressed) return;
if(flashlight_on) {
flashlight_on = false;
rootNode.removeLight(flashlight);
} else {
flashlight_on = true;
rootNode.addLight(flashlight);
}
}
}
}
[/java]
The weapons get displayed correctly, but do not rotate with the camera (I thought the line: player.setLocalRotation(cam.getRotation()); would solve this, but it doesn’t…). Secondly the weapons get stuck if I move to a hill. I read of something like a second viewport but I’ve got no idea what this actually is