Hey,
I’m trying to make a first-person camera with a weapon, but somehow I’m not affected by the gravity and physics and my sword falls through the ground. I’ve added [java]playerNode.addControl(player)[/java] which I thought would make the player’s node follow the CharacterControl but it does not work and I can’t figure out what is the problem.
Here is my code:
[java]
package mygame;
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Node;
import com.jme3.scene.control.CameraControl.ControlDirection;
import com.jme3.terrain.geomipmap.TerrainLodControl;
import com.jme3.terrain.geomipmap.TerrainQuad;
import com.jme3.terrain.heightmap.AbstractHeightMap;
import com.jme3.terrain.heightmap.ImageBasedHeightMap;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
/**
-
test
-
@author jadam
*/
public class Main extends SimpleApplication implements ActionListener,AnimEventListener{
private CameraNode cn;
private AnimChannel channel;
private AnimControl control;
private Node sword;
private CharacterControl player;
private Node playerNode;
private RigidBodyControl landscape;
private BulletAppState bulletAppState;
//Temporary vectors used on each frame.
//They here to avoid instanciating new vectors on each frame
private Vector3f camDir = new Vector3f();
private Vector3f camLeft = new Vector3f();private TerrainQuad terrain;
private Material mat_terrain;
private boolean left = false, right = false, up = false, down = false;
private Vector3f walkDirection = new Vector3f();
public static void main(String[] args) {
Main app = new Main();
app.start();
}
private void initTerrain()
{
/** 1. Create terrain material and load four textures into it. */
mat_terrain = new Material(assetManager,
“Common/MatDefs/Terrain/Terrain.j3md”);/** 1.1) Add ALPHA map (for red-blue-green coded splat textures) */ mat_terrain.setTexture("Alpha", assetManager.loadTexture( "Textures/Terrain/splat/alphamap.png")); /** 1.2) Add GRASS texture into the red layer (Tex1). */ Texture grass = assetManager.loadTexture( "Textures/Terrain/splat/grass.jpg"); grass.setWrap(WrapMode.Repeat); mat_terrain.setTexture("Tex1", grass); mat_terrain.setFloat("Tex1Scale", 64f); /** 1.3) Add DIRT texture into the green layer (Tex2) */ Texture dirt = assetManager.loadTexture( "Textures/Terrain/splat/dirt.jpg"); dirt.setWrap(WrapMode.Repeat); mat_terrain.setTexture("Tex2", dirt); mat_terrain.setFloat("Tex2Scale", 32f); /** 1.4) Add ROAD texture into the blue layer (Tex3) */ Texture rock = assetManager.loadTexture( "Textures/Terrain/splat/road.jpg"); rock.setWrap(WrapMode.Repeat); mat_terrain.setTexture("Tex3", rock); mat_terrain.setFloat("Tex3Scale", 128f); /** 2. Create the height map */ AbstractHeightMap heightmap = null; Texture heightMapImage = assetManager.loadTexture( "Textures/Terrain/splat/mountains512.png"); heightmap = new ImageBasedHeightMap(heightMapImage.getImage()); heightmap.load(); int patchSize = 65; terrain = new TerrainQuad("my terrain", patchSize, 513, heightmap.getHeightMap()); /** 4. We give the terrain its material, position & scale it, and attach it. */ terrain.setMaterial(mat_terrain); terrain.setLocalTranslation(0, -100, 0); terrain.setLocalScale(2f, 1f, 2f); rootNode.attachChild(terrain); /** 5. The LOD (level of detail) depends on were the camera is: */ TerrainLodControl control = new TerrainLodControl(terrain, getCamera()); terrain.addControl(control); CollisionShape sceneShape = CollisionShapeFactory.createMeshShape((Node) terrain); landscape = new RigidBodyControl(sceneShape, 0); terrain.addControl(landscape); bulletAppState.getPhysicsSpace().add(terrain);
}
private void initPlayer()
{
playerNode = new Node(“player node”);
flyCam.setMoveSpeed(100);
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
player = new CharacterControl(capsuleShape, 0.05f);
player.setJumpSpeed(20);
player.setFallSpeed(30);
player.setGravity(30);
player.setPhysicsLocation(new Vector3f(0, 200, 0));
bulletAppState.getPhysicsSpace().add(player);sword = (Node) assetManager.loadModel(“Scenes/Cube.002.mesh.xml”);
cn = new CameraNode("first person camera node",cam); cn.setControlDir(ControlDirection.CameraToSpatial); playerNode.addControl(player); playerNode.attachChild(sword); playerNode.attachChild(cn); rootNode.attachChild(playerNode); control = sword.getControl(AnimControl.class); control.addListener(this); channel = control.createChannel(); channel.setAnim("sword idle"); channel.setLoopMode(LoopMode.Loop);
}
@Override
public void simpleInitApp() {
/** Set up Physics */
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
//bulletAppState.getPhysicsSpace().enableDebug(assetManager);
viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));AmbientLight al = new AmbientLight(); al.setColor(ColorRGBA.White.mult(1.3f)); rootNode.addLight(al); setUpKeys(); initTerrain(); initPlayer();
}
public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
if (animName.equals(“sword swing”)) {
channel.setAnim(“sword idle”, 0.50f);
channel.setLoopMode(LoopMode.Loop);
channel.setSpeed(1f);
}
}
private void setUpKeys() {
inputManager.addMapping(“Left”, new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping(“Right”, new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping(“Up”, new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping(“Down”, new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping(“Jump”, new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping(“ATTACK”, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(this, “Left”);
inputManager.addListener(this, “Right”);
inputManager.addListener(this, “Up”);
inputManager.addListener(this, “Down”);
inputManager.addListener(this, “Jump”);
inputManager.addListener(this, “ATTACK”);
}
public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
// unused
}
@Override
public void simpleUpdate(float tpf) {
camDir.set(cam.getDirection()).multLocal(0.6f);
camLeft.set(cam.getLeft()).multLocal(0.4f);
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());
}
player.setWalkDirection(walkDirection);
//cam.setLocation(player.getPhysicsLocation());
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
public void onAction(String name, boolean isPressed, float tpf) {
if (isPressed)
{
if (name.equals("ATTACK"))
{
channel.setAnim("sword swing");
channel.setLoopMode(LoopMode.DontLoop);
}
}
if (name.equals("Left")) {
left = isPressed;
} else if (name.equals("Right")) {
right= isPressed;
} else if (name.equals("Up")) {
up = isPressed;
} else if (name.equals("Down")) {
down = isPressed;
} else if (name.equals("Jump")) {
if (isPressed) { player.jump(); }
}
}
}
[/java]
Thanks in advance!