Camera switch

I now have two cameras with different angles
One is in the first person
One is in the third person
I want to switch between two shots
I need a little guidance

So, may be you can tie each one of them to a node with a perspective and just switch your object between those nodes.

1 Like

Here’s a similar response

I did the same thing

But there was a problem with switching cameras

I can’t look up and down when I switch to this camera even if I set the vertical range

Yes, my two cameras are bound to different locations in the model and each location has Node nodes


The camera created first will not be able to look up and down
Cameras created at the last can normally look up and down

What is the stimulus you are using ? A Drag to rotate ? Or other manual means ?

I used the chase camera to provide the rotation

image
The camera’s vertical arc is locked at 0.5

Hmm, without looking at the internals of chase cam, i am guessing now that the camera rotation input is a singleton or you are treating it as a singleton so that is why only the second instance can move the camera, let me take a look at the code and reply back.

1 Like

https://www.icyboxs.com/icyboxs/newGame.rar
This is the code

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Role;

import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.BaseAppState;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.ChaseCamera;
import com.jme3.input.InputManager;
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.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.debug.Arrow;
import com.jme3.scene.debug.WireFrustum;
import com.jme3.shadow.ShadowUtil;
/**
 *
 * @author Administrator
 */
    public class model extends BaseAppState implements ActionListener{
   // public final static String FIRE = "fire";
    public final static String  DEBUG = "DEBUG";
    public final static String FORWARD = "forward";
    public final static String BACKWARD = "backward";
    public final static String LEFT = "left";
    public final static String RIGHT = "right";
    public final static String V = "v";
    public final static String JUMP = "jump";
    public int v1= 0;
    
    private AssetManager assetManager ;
    private BulletAppState bulletAppState;
    private TerrainChaseCamera chaseCam;
    private ChaseCamera chaseCam1;
    private InputManager inputManager;
    private InputManager minputManager;
    private Camera cam;
    private Camera cam1;
    private Node character = new Node("character");
    private Node model;
     //方向控制器
    private CharacterControl player;
    private Vector3f walkDirection = new Vector3f();
    private Vector3f walkDirectioni = new Vector3f();
    private Vector3f camDir = new Vector3f();
    private Vector3f camLeft = new Vector3f();
    private boolean left = false, right = false, up = false, down = false, v=false;

    @Override
    protected void initialize(Application app) {
       
        bulletAppState = app.getStateManager().getState(BulletAppState.class);
        assetManager = app.getAssetManager();
        inputManager = app.getInputManager();
        
        cam=app.getCamera();


        app.getStateManager().attach(bulletAppState);//添加物理世界
        float radius = 0.5f;// 胶囊半径0.3米
        float height = 3.3f;// 胶囊身高1.8米
        float stepHeight = 0.5f;// 角色步高0.5米
        model = (Node) assetManager.loadModel("Models/Test/hecheng.j3o");
        model.move(0, -(height/2+radius), 0);
        character.attachChild(model);
        CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(radius, height, 1);
        player = new CharacterControl(capsuleShape, stepHeight);
        player.setJumpSpeed(10f);// 起跳速度
        player.setFallSpeed(20f);// 坠落速度
        player.setGravity(9.8f * 3);// 重力加速度
        character.addControl(player);
        bulletAppState.getPhysicsSpace().add(player);
       // chaseCam = new TerrainChaseCamera(cam, model.getChild("Bip002"), inputManager);
//        
//        chaseCam.setDragToRotate(false); //把鼠标锁定在窗口里
//        chaseCam.setInvertVerticalAxis(true);//反转鼠标的垂直轴移动
//        chaseCam.setMinDistance(10f);
//        chaseCam.setMaxDistance(10f);
//        
//

                
        chaseCam1 = new ChaseCamera(cam, character, inputManager);
        chaseCam1.setDragToRotate(false); //把鼠标锁定在窗口里
        chaseCam1.setInvertVerticalAxis(true);//反转鼠标的垂直轴移动
        chaseCam1.setMinDistance(0f);
        chaseCam1.setMaxDistance(10f);
        chaseCam1.setLookAtOffset(new Vector3f(0,1.5f,0));
  
       
 
 
        chaseCam = new TerrainChaseCamera(cam, model.getChild("Bip002"), inputManager);
        chaseCam.setDragToRotate(false); //把鼠标锁定在窗口里
        chaseCam.setInvertVerticalAxis(true);//反转鼠标的垂直轴移动
        chaseCam.setMinDistance(10f);
        chaseCam.setMaxDistance(10f);
//        chaseCam.setLookAtOffset(new Vector3f(0,1.5f,0));
//        chaseCam.setMinVerticalRotation(-1.57f);
//        chaseCam.setMaxVerticalRotation(1.57f);
        chaseCam.setLookAtOffset(new Vector3f(0,1.5f,0));
        

    }
    private void initKeys() {
       
        inputManager.addMapping(DEBUG, new KeyTrigger(KeyInput.KEY_F1));
        inputManager.addMapping(LEFT, new KeyTrigger(KeyInput.KEY_A));
        inputManager.addMapping(RIGHT, new KeyTrigger(KeyInput.KEY_D));
        inputManager.addMapping(FORWARD, new KeyTrigger(KeyInput.KEY_W));
        inputManager.addMapping(BACKWARD, new KeyTrigger(KeyInput.KEY_S));
        inputManager.addMapping(JUMP, new KeyTrigger(KeyInput.KEY_SPACE));
        inputManager.addMapping(V, new KeyTrigger(KeyInput.KEY_V));
        inputManager.addListener(this, DEBUG, LEFT,RIGHT,FORWARD,BACKWARD,JUMP,V);
    }
    
    @Override
    //在应用程序状态分离后或在应用程序关闭期间调用(如果状态仍处于附加状态)。
    protected void cleanup(Application aplctn) {
     
    }

    @Override
    //当状态完全启用时调用,即:已附加并且 isEnabled() 为 true 或当状态附加后 setEnabled() 状态发生变化时调用。
    protected void onEnable() {
       SimpleApplication simpleApp = (SimpleApplication) getApplication();
       simpleApp.getRootNode().attachChild(character);
       //bulletAppState.setDebugEnabled(true);
         initKeys();

      //simpleApp.getRootNode().addControl(new RoleControl(simpleApp.getInputManager(),simpleApp.getCamera()));
      //  throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    
    }

    @Override
    //当状态先前启用但现在由于调用 setEnabled(false) 或正在清理状态而被禁用时调用。
    protected void onDisable() {
        character.removeFromParent();
      //  throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    @Override
   public void update(float tpf) {

      inputManager.setCursorVisible(false);
        camDir.set(cam.getDirection()).multLocal(0.001f);
        camLeft.set(cam.getLeft()).multLocal(0.001f);
        camDir.y = 0;
        camLeft.y = 0;
        walkDirection.set(0, 0, 0);
        
        // 计算运动方向
        boolean changed = false;
        if (left) {
            walkDirectioni.addLocal(camLeft);
            walkDirection.addLocal(camLeft);
            
            changed = true;
        }
        if (right) {
            walkDirectioni.addLocal(camLeft.negate());
           
            walkDirection.addLocal(camLeft.negate());
           
            changed = true;
        }
        if (up) {
            walkDirectioni.addLocal(camDir);
        
            walkDirection.addLocal(camDir);
      
            changed = true;
        }
        if (down) {
            walkDirectioni.addLocal(camDir.negate());
        
            walkDirection.addLocal(camDir.negate());
            
            changed = true;
        }
      switch(v1){
        case 0 :
        chaseCam.setEnabled(true);
        chaseCam1.setEnabled(false);
        chaseCam.setLookAtOffset(new Vector3f(0,1.5f,0));
        player.setViewDirection(chaseCam.setRotateAround( new Vector3f(0,0,0),new Vector3f(0,1,0),-(chaseCam.getHorizontalRotation())).setY(0));
       break; //可选
          case 1 :
        chaseCam.setEnabled(false);
        chaseCam1.setEnabled(true);
//        chaseCam1.setMaxVerticalRotation(1.57f);
//        chaseCam1.setMaxVerticalRotation(-1.57f);
       // chaseCam1.setDownRotateOnCloseViewOnly(false);
        player.setViewDirection(walkDirectioni);
       break; //可选
    //你可以有任意数量的case语句
    default : //可选
       //语句
          }
        if (changed) {
             
            walkDirectioni.y = 0.0f;// 将行走速度的方向限制在水平面上。
            walkDirectioni.normalizeLocal();// 单位化
            walkDirectioni.multLocal(0.001f);// 改变速率
            walkDirection.y = 0;// 将行走速度的方向限制在水平面上。
            walkDirection.normalizeLocal();// 单位化
            walkDirection.multLocal(0.3f);// 改变速率
            
        }
        if (walkDirection.length() != 0f) {
             
        }
             

     
       player.setWalkDirection(walkDirection);
      // player.setViewDirection(walkDirectioni);
      
      //  player.setViewDirection(walkDirection);  setViewDirection
    
    }

    @Override
    public void onAction(String name, boolean isPressed, float tpf) {
       if (DEBUG.equals(name) && isPressed) {
        
           System.err.println("按下F1");
            boolean debugEnabled = bulletAppState.isDebugEnabled();
            bulletAppState.setDebugEnabled(!debugEnabled);
        } else if (LEFT.equals(name)) {
            left = isPressed;
        } else if (RIGHT.equals(name)) {
            right = isPressed;
        } else if (FORWARD.equals(name)) {
            up = isPressed;
        } else if (BACKWARD.equals(name)) {
            down = isPressed;
        }else if(V.equals(name)) {
            if(!isPressed){
          switch(v1){
        case 0 :
//        System.err.println();
//        chaseCam = new TerrainChaseCamera(cam, model.getChild("Bip001"), inputManager);
//        chaseCam.setDragToRotate(false); //把鼠标锁定在窗口里
//        chaseCam.setInvertVerticalAxis(true);//反转鼠标的垂直轴移动
//        chaseCam.setMinDistance(20f);
//        chaseCam.setMaxDistance(20f);
       
         v1++;
       break; //可选
          case 1 :
        
            v1=0;
       break; //可选
    //你可以有任意数量的case语句
    default : //可选
       //语句
          }
        }
            v = isPressed;
        }else if (JUMP.equals(name) && isPressed) {
            if(player.onGround()==true){
                player.jump();
                player.warp(walkDirection);
            }
            
            	//System.err.println(player.onGround());
            //	player.warp(walkDirection);
        }
 
    }
    
     /**
     * 创建一个箭头
     * 
     * @param vec3  箭头向量
     * @param color 箭头颜色
     */
    private void createArrow(Vector3f vec3, ColorRGBA color) {
        // 创建材质,设定箭头的颜色
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", color);

        // 创建几何物体,应用箭头网格。
        Geometry geom = new Geometry("arrow", new Arrow(vec3));
        geom.setMaterial(mat);

        // 添加到场景中
        SimpleApplication simpleApp = (SimpleApplication) getApplication();
       simpleApp.getRootNode().attachChild(geom);
    }
    
public  Geometry createCameraFrustum(Camera cam) {
	
	Vector3f[] points = new Vector3f[8];
	for (int i = 0; i < 8; i++) {
		points[i] = new Vector3f();
	}
	
	Camera frustumCam = cam.clone();
	frustumCam.setLocation(	cam.getLocation());
	frustumCam.lookAt(Vector3f.UNIT_Z, Vector3f.ZERO);
	ShadowUtil.updateFrustumPoints2(frustumCam, points);
	Mesh mesh = WireFrustum.makeFrustum(points);
	
	Geometry frustumGeo = new Geometry("Viewing.Frustum", mesh);
	Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
	mat.setColor("Color", ColorRGBA.Red);
	frustumGeo.setMaterial(mat);
	frustumGeo.setCullHint(Spatial.CullHint.Never);
	frustumGeo.setShadowMode(RenderQueue.ShadowMode.Off);
	
	return frustumGeo;
}
    
    
}

1 Like

Switch camera

Initializing the camera

1 Like

I solved the problem
But I don’t know why
I went through all the possible questions(对于这个问题我做了很多尝试(That’s what I originally meant because the translator didn’t translate it right))

switch(v1){
        case 0 :
        chaseCam.setEnabled(true);
        chaseCam1.setEnabled(false);
        chaseCam.setLookAtOffset(new Vector3f(0,1.5f,0));
        player.setViewDirection(chaseCam.setRotateAround( new Vector3f(0,0,0),new Vector3f(0,1,0),-(chaseCam.getHorizontalRotation())).setY(0));
       break; //可选
          case 1 :
        chaseCam.setEnabled(false);
        chaseCam1.setEnabled(true);
        chaseCam1.setInvertVerticalAxis(true);
//        chaseCam1.setMaxVerticalRotation(1.57f);
//        chaseCam1.setMaxVerticalRotation(-1.57f);
       // chaseCam1.setDownRotateOnCloseViewOnly(false);
        player.setViewDirection(walkDirectioni);
       break; //可选
    //你可以有任意数量的case语句
    default : //可选
       //语句
          }

In case 1 to join chaseCam1. SetInvertVerticalAxis (true);

My view switch function became normal

1 Like