Rotating the Camera and Player Node Towards Enemy

I have been trying to get the camera and player node to rotate towards enemy automatically in vain, the action being basically the player locking on to the enemy. I am using a CameraNode that is attached behind the player, so that it will always show the player and enemy on screen. Currently I am using camNode.lookAt() placed in the update function, and while it does lock on to the enemy, it does not stay behind the player node. I would like it to orbit around the player node if possible. Can I ask for suggestions?



I would also like to have the player rotate towards the enemy automatically. playerNode.lookAt() makes it look weird for some reason, with the camera focusing on the player instead(?), so if I may ask for alternatives? I found this topic which I’ll try later.



Here is the initialization of the CameraNode, basically a piece of code I took from TestCameraNode.java from here.



[java]// Disable the default flyby cam

flyCam.setEnabled(false);

//create the camera Node

camNode = new CameraNode(“Camera Node”, cam);

//This mode means that camera copies the movements of the target:

camNode.setControlDir(ControlDirection.SpatialToCamera);

//Attach the camNode to the target:

playerNode.attachChild(camNode);

//Move camNode, e.g. behind and above the target:

camNode.setLocalTranslation(new Vector3f(0, 2, 10));

//Rotate the camNode to look at the target:

camNode.lookAt(enemy.getLocalTranslation(), Vector3f.UNIT_Y);

[/java]



I could post the full code if necessary, but the code is written specifically for Android, so there’s that.

You may want to switch to a chase cam.



[java]ChaseCamera chaseCam = new ChaseCamera(cam, model, inputManager);

chaseCam.setDefaultDistance(.005f);

chaseCam.setMaxDistance(10f);

chaseCam.setDefaultHorizontalRotation(0f);

chaseCam.setDefaultVerticalRotation(0f);

chaseCam.setZoomSensitivity(1);

cam.setFrustumFar(farFrustum);

float aspect = (float)cam.getWidth() / (float)cam.getHeight();

cam.setFrustumPerspective( 45f, aspect, 0.1f, cam.getFrustumFar() );

chaseCam.setUpVector(Vector3f.UNIT_Y);

chaseCam.setMinDistance(.005f);

chaseCam.setToggleRotationTrigger(new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));

chaseCam.setInvertVerticalAxis(true);[/java]



etc, etc, amen. This is set up to be first person/chase cam… anyways… should do what you want.

My problem with the chase cam was how it completely focuses only on the targeted model, and approaches it from different angles according to its location instead of staying behind it, which was the main reason why I chose to use Camera Node, although that is most probably a problem on my part though. However, I do like how the camera lags behind when chasing the target, is there a way to achieve a similar effect with node cams?



And this is embarrassing, but apparently all I needed was to make the player node look at the enemy node. The reason why it looked weird when I tried it the first time was because I got confused which was considered as the front and the back on the z axis. Since positive z was behind the default cam, I used that as my “behind the character” direction. Using playerNode.lookAt() caused the camera to automatically be at a negative z position relative to the player node, and thus looking “behind” the character. After adjusting that, the camera stays behind the player and has the enemy in sight, and rotates the camera and player automatically as the player moves around.



I am so sorry for the trouble.

I dislike some aspects of chase cam and some aspects of camera node as well. Here’s the solution I intend to work on when I have a little more time:



Make the cameraNode not actually be attached to the player, but have it follow the player. I plan to make the speed increase with distance from the player, so it catches up and slows as it nears you.



The exact details of how it follows and what it aims at really depend on the game, in my game I don’t want the node to rotate at all (it’s a top-down type game), in yours you want it to turn towards the enemy.

Hello again. Since last time, I’ve implemented physics into my program, which then causes the cameraNode to no longer follow behind the player geometry, although it is still looking at the enemy geometry. Translation of the playerNode also no longer affected the player geometry. I’ve tinkered around, and noticed that the cameraNode follows the playerNode around, but the playerNode does not follow the movements of the player geometry. So I changed my function that moves the player to this:



[java]

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); }

if (right) { walkDirection.addLocal(camLeft.negate()); }

if (forward) { walkDirection.addLocal(camDir); }

if (back) { walkDirection.addLocal(camDir.negate()); }

playerControl.setWalkDirection(walkDirection);



//relocate the playerNode to the location of the player

playerNode.setLocalTranslation(player.getWorldTranslation());

//make the playerNode lookAt the enemy; the camNode follows

playerNode.lookAt(enemy.getWorldTranslation(), Vector3f.UNIT_Y);

[/java]



This worked, and the cameraNode now stays behind the player geometry, but now the geometry twitches about. I’m thinking it is because I forced the location change of the playerNode? Any ideas on better ways to achieve the same effect?



If it is of any relation, this is the code I used to set the camera:

[java]

// Disable the default flyby cam

flyCam.setEnabled(false);



//create the camera Node

camNode = new CameraNode(“Camera Node”, cam);

//This mode means that camera copies the movements of the target:

camNode.setControlDir(ControlDirection.SpatialToCamera);

//Attach the camNode to the target:

playerNode.attachChild(camNode);

//Move camNode, e.g. behind and above the target:

camNode.setLocalTranslation(new Vector3f(0, 2, -10));

//Rotate the camNode to look at the target:

camNode.lookAt(enemy.getLocalTranslation(), Vector3f.UNIT_Y);

[/java]

Please read the tutorial: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:physics



The section “Kinematic vs Dynamic vs Static” might be the explanation. You can’t just move physics by setting translations/rotations unless they are kinematic (but then they don’t collide).