Prevent flying when backwalking and lock camera to a max. angel?

Hey Guys, is there any possbility of preventing a character to fly when looking at the ground and backwalking? And is there a way to prevent the camera to do a barrel roll? :smiley:
Would be nice to have a quick answer, thx ^^

replace:

 walkDirection.addLocal(camDir);

and

walkDirection.addLocal(camLeft);

with:

walkDirection.addLocal(camDir.setY(0));

and

walkDirection.addLocal(camLeft.setY(0));

Well that didnt change anything, I can still fly, and I can still do a barrel roll

can you post your code here?

I´ll post everything here:

package mygame;

/*
 * Copyright (c) 2009-2010 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
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.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
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.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.FogFilter;
import com.jme3.post.filters.LightScatteringFilter;
import com.jme3.post.ssao.SSAOFilter;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.shadow.DirectionalLightShadowFilter;
import com.jme3.shadow.DirectionalLightShadowRenderer;
import com.jme3.system.AppSettings;
import com.jme3.texture.Texture;
import com.jme3.util.SkyFactory;
 
 
public class Main extends SimpleApplication
        implements ActionListener{
 
  private Spatial levelOne;
  private BulletAppState bulletAppState;
  private RigidBodyControl landscape;
  private CharacterControl player;
  private Vector3f walkDirection = new Vector3f();
  private boolean left = false, right = false, up = false, down = false;
 
 
  public static void main(String[] args) {
    Main app = new Main();
     //some presets
    AppSettings settings = new AppSettings(true);
    settings.setResolution(1280,720);
    settings.setFrameRate(60);
    //settings.setFullscreen(true);
    app.setSettings(settings);
    //app.setShowSettings(false);
    app.setPauseOnLostFocus(true);
    app.start();
  }
 
  public void simpleInitApp() {  
    //don't show stats
    setDisplayFps(false);
    setDisplayStatView(false);

    /** A white, directional light source */ 
    DirectionalLight sun = new DirectionalLight();
    sun.setDirection((new Vector3f(-10f, -10f, -10f)).normalizeLocal());
    sun.setColor(ColorRGBA.White);
    rootNode.addLight(sun); 
 /** Add fog to a scene */
 /** Add fog to a scene */
 FilterPostProcessor fpp=new FilterPostProcessor(assetManager);
 FogFilter fog=new FogFilter();
 fog.setFogColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.0f));
 fog.setFogDistance(155);
 fog.setFogDensity(3.0f);
 fpp.addFilter(fog);
 viewPort.addProcessor(fpp);
/* this shadow needs a directional light */
DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(assetManager, 1024, 2);
dlsr.setLight(sun);
viewPort.addProcessor(dlsr); 
 

        /** Write text on the screen (HUD) */
        guiNode.detachAllChildren();
        guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
        BitmapText helloText = new BitmapText(guiFont, false);
        helloText.setSize(guiFont.getCharSet().getRenderedSize());
        helloText.setText("DECISION PRE-ALPHA 0.1");
        helloText.setLocalTranslation(10, helloText.getLineHeight(), 0);
        guiNode.attachChild(helloText);
 


    
    bulletAppState = new BulletAppState();
    bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);//for bullets
    stateManager.attach(bulletAppState);
    //bulletAppState.getPhysicsSpace().enableDebug(assetManager);
    // We re-use the flyby camera for rotation, while positioning is handled by physics
    viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
    flyCam.setMoveSpeed(100);
    setUpKeys();
    setUpLight();
    //Preload Levels
    levelOne = assetManager.loadModel("Scenes/Scene1/scene1.j3o");
    levelOne.setLocalScale(5f);
    //Set up physics and add level/player to scenegraph
    setLevel(levelOne);
  }
 
  private void setLevel(Spatial level) {
      // We set up collision detection for the scene by creating a
    // compound collision shape and a static RigidBodyControl with mass zero.
    CollisionShape sceneShape =
            CollisionShapeFactory.createMeshShape((Node) level);
    landscape = new RigidBodyControl(sceneShape, 0);
    level.addControl(landscape);
 
    // We set up collision detection for the player by creating
    // a capsule collision shape and a CharacterControl.
    // The CharacterControl offers extra settings for
    // size, stepheight, jumping, falling, and gravity.
    // We also put the player in its starting position.
    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, 14, 120));
    // We attach the scene and the player to the rootnode and the physics space,
    // to make them appear in the game world.
    rootNode.attachChild(level);
    bulletAppState.getPhysicsSpace().add(landscape);
    bulletAppState.getPhysicsSpace().add(player);
  }
 
  private PhysicsSpace getPhysicsSpace() {
        return bulletAppState.getPhysicsSpace();
  }
 
  private void setUpLight() {

  }
 
  /** We over-write some navigational key mappings here, so we can
   * add physics-controlled walking and jumping: */
  private void setUpKeys() {
    inputManager.deleteMapping(INPUT_MAPPING_EXIT);
    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("Quit", new KeyTrigger(KeyInput.KEY_ESCAPE));
    inputManager.addListener(this, "Left");
    inputManager.addListener(this, "Right");
    inputManager.addListener(this, "Up");
    inputManager.addListener(this, "Down");
    inputManager.addListener(this, "Jump");
    inputManager.addListener(this, "Quit"); // listen for ESC key to close game
  }
 
 
 
  /** These are our custom actions triggered by key presses.
   * We do not walk yet, we just keep track of the direction the user pressed. */
  public void onAction(String binding, boolean value, float tpf) {
    if (binding.equals("Left")) {
      if (value) { left = true; } else { left = false; }
    } else if (binding.equals("Right")) {
      if (value) { right = true; } else { right = false; }
    } else if (binding.equals("Up")) {
      if (value) { up = true; } else { up = false; }
    } else if (binding.equals("Down")) {
      if (value) { down = true; } else { down = false; }
    } else if (binding.equals("Jump")) {
      player.jump();
    } else if (binding.equals("Quit")) {
      stop(); // simple way to close game
    }
  }
 
 
  /**
   * This is the main event loop--walking happens here.
   * We check in which direction the player is walking by interpreting
   * the camera direction forward (camDir) and to the side (camLeft).
   * The setWalkDirection() command is what lets a physics-controlled player walk.
   * We also make sure here that the camera moves with player.
   */
  @Override
  public void simpleUpdate(float tpf) {
   
        Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
        walkDirection.set(0, 0, 0);
        if (left)  { walkDirection.addLocal(camLeft.setY(0)); }
        if (right) { walkDirection.addLocal(camLeft.negate()); }
        if (up)    { walkDirection.addLocal(camDir.setY(0)); }
        if (down)  { walkDirection.addLocal(camDir.negate()); }
        player.setWalkDirection(walkDirection);
        cam.setLocation(player.getPhysicsLocation());  
   
  }
}

try replace this:

  public void simpleUpdate(float tpf) {
   
        Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
        walkDirection.set(0, 0, 0);
        if (left)  { walkDirection.addLocal(camLeft.setY(0)); }
        if (right) { walkDirection.addLocal(camLeft.negate()); }
        if (up)    { walkDirection.addLocal(camDir.setY(0)); }
        if (down)  { walkDirection.addLocal(camDir.negate()); }
        player.setWalkDirection(walkDirection);
        cam.setLocation(player.getPhysicsLocation());  
   
  }

with this:

  public void simpleUpdate(float tpf) {
   
        Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
        walkDirection.set(0, 0, 0);
        if (left)  { walkDirection.addLocal(camLeft.setY(0)); }
        if (right) { walkDirection.addLocal(camLeft.negate().setY(0)); }
        if (up)    { walkDirection.addLocal(camDir.setY(0)); }
        if (down)  { walkDirection.addLocal(camDir.negate().setY(0)); }
            if(cam.getDirection().getY() < 0)walkDirection.addLocal(camUp.setY(0).negate());
            else walkDirection.addLocal(camUp.setY(0));
        player.setWalkDirection(walkDirection);
        cam.setLocation(player.getPhysicsLocation());  
   
  }
  1. It did not recognize “camUp”, so I changed it to “camDir”. It pushes me backwards :confused:

oh sorry, try this:

  public void simpleUpdate(float tpf) {
   
        Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
        walkDirection.set(0, 0, 0);
        if (left)  { walkDirection.addLocal(camLeft.setY(0)); }
        if (right) { walkDirection.addLocal(camLeft.negate().setY(0)); }
        if (up)    { walkDirection.addLocal(camDir.setY(0)); }
        if (down)  { walkDirection.addLocal(camDir.negate().setY(0)); }
            if(cam.getDirection().getY() < 0)walkDirection.addLocal(cam.getUp().setY(0).negate());
            else walkDirection.addLocal(cam.getUp().setY(0));
        player.setWalkDirection(walkDirection);
        cam.setLocation(player.getPhysicsLocation());  
   
  }

It still pushes me back a little:/

try

    public void simpleUpdate(float tpf) {
       
            Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
            Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
            walkDirection.set(0, 0, 0);
            if (left)  { walkDirection.addLocal(camLeft.setY(0)); }
            if (right) { walkDirection.addLocal(camLeft.negate().setY(0)); }
            if (up)    { 
                   walkDirection.addLocal(camDir.setY(0)); 
    
    
                    if(cam.getDirection().getY() < 0)walkDirection.addLocal(cam.getUp().setY(0));
                    else walkDirection.addLocal(cam.getUp().setY(0).negate(0));
            }
            if (down)  { 
                 walkDirection.addLocal(camDir.negate().setY(0));
            
                if(cam.getDirection().getY() < 0)walkDirection.addLocal(cam.getUp().setY(0).negate());
                else walkDirection.addLocal(cam.getUp().setY(0));
            }
           if(cam.getUp().y < 0){
                     cam.lookAtDirection( new Vector3f(0,cam.getDirection().y,0),new Vector3f(cam.getUp().x,0, cam.getUp().z));
            }
            player.setWalkDirection(walkDirection);
            cam.setLocation(player.getPhysicsLocation());  
       
      }

Worked! Any Idea for the camera lock problem now? .3

add

if(cam.getUp().y < 0){
      cam.lookAtDirection( new Vector3f(0,cam.getDirection().y,0),new Vector3f(cam.getUp().x,0, cam.getUp().z));
 }

before

    player.setWalkDirection(walkDirection);
    cam.setLocation(player.getPhysicsLocation());  

like:

 public void simpleUpdate(float tpf) {
       
            Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
            Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
            walkDirection.set(0, 0, 0);
            if (left)  { walkDirection.addLocal(camLeft.setY(0)); }
            if (right) { walkDirection.addLocal(camLeft.negate().setY(0)); }
            if (up)    { 
                   walkDirection.addLocal(camDir.setY(0)); 
    
    
                    if(cam.getDirection().getY() < 0)walkDirection.addLocal(cam.getUp().setY(0));
                    else walkDirection.addLocal(cam.getUp().setY(0).negate(0));
            }
            if (down)  { 
                 walkDirection.addLocal(camDir.negate().setY(0));
            
                if(cam.getDirection().getY() < 0)walkDirection.addLocal(cam.getUp().setY(0).negate());
                else walkDirection.addLocal(cam.getUp().setY(0));
            }
           if(cam.getUp().y < 0){
                     cam.lookAtDirection( new Vector3f(0,cam.getDirection().y,0),new Vector3f(cam.getUp().x,0, cam.getUp().z));
            }
            player.setWalkDirection(walkDirection);
            cam.setLocation(player.getPhysicsLocation());  
       
      }

Thx mate <3 You saved my sweet ass :smiley:

Found an issue. When looking downwards, my movement get´s faster. I changed the multLocal so the char walks way slower.But when looking to the ground, he gains much speed :confused:

change movingspeed value as you like

public void simpleUpdate(float tpf) {
            float movingspeed = 0.6f;   // speed for the player

            Vector3f camDir = cam.getDirection().clone().multLocal(movingspeed);
            Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
            Vector3f camUp = new Vector3f(0f,0f,0f);
            camUp.set(cam.getUp()).multLocal(movingspeed*(1-(cam.getUp().getY())));
            walkDirection.set(0, 0, 0);
            if (left)  { walkDirection.addLocal(camLeft.setY(0)); }
            if (right) { walkDirection.addLocal(camLeft.negate().setY(0)); }
            if (up)    { 
                   walkDirection.addLocal(camDir.setY(0)); 
    
    
                    if(cam.getDirection().getY() < 0)walkDirection.addLocal(camUp.setY(0));
                    else walkDirection.addLocal(camUp.setY(0).negate());
            }
            if (down)  { 
                 walkDirection.addLocal(camDir.negate().setY(0));
            
                if(cam.getDirection().getY() < 0)walkDirection.addLocal(camUp.setY(0).negate());
                else walkDirection.addLocal(camUp.setY(0));
            }
           if(cam.getUp().y < 0){
                     cam.lookAtDirection( new Vector3f(0,cam.getDirection().y,0),new Vector3f(cam.getUp().x,0, cam.getUp().z));
            }
            player.setWalkDirection(walkDirection);
            cam.setLocation(player.getPhysicsLocation());  
       
      }

Do you want to marry me? xD :smiley: Your saving me again ^^

no thanks xD :smile:
my age is not ready for marriage xD

One little thing I noticed was this:

                if(cam.getDirection().getY() < 0)walkDirection.addLocal(camUp.setY(0));
                else walkDirection.addLocal(camUp.setY(0).negate(0));

You cannot set a negate 0. It would be like this:

                if(cam.getDirection().getY() < 0)walkDirection.addLocal(camUp.setY(0));
                else walkDirection.addLocal(camUp.setY(0).negate());

oh that was typo xD

All fine :smiley: You set the moving speed to the multLocal for cam.getDirection, right? I understood that, I can also do the same for the cam.getLeft, or?