Hello, this is another stupid question from me
Let’s say I have some enemies and I want them to look at the camera position. LookAt(cam.getLocation(),Vector3f.ZERO) works nice, however… if I look on the ground when I’m near enemy they look like they are lying on the ground…
I hope you guys understand what I mean and can help me!
try
LookAt(cam.getLocation(),Vector3f.UNIT_Y);
Thanks, but I already tried it. I have tried Vector3f.UNIT_Y, Vector3f.UNIT_X, Vector3f.UNIT_Z, Vector3f.UNIT_XYZ or
new Vector3f (0,1,0) or new Vector3f(0,-1,0).
Here is a test case so all can see what I mean:
[java]
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.light.DirectionalLight;
import com.jme3.math.Quaternion;
import com.jme3.scene.shape.Box;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
public class Main extends SimpleApplication {
Node model;
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
flyCam.setMoveSpeed(20f);
cam.setRotation(new Quaternion(0.30f,-0.69f,0.42f,0.49f));
cam.setLocation(new Vector3f(13f,43f,6f));
cam.setAxes(cam.getLeft(), cam.getUp(), new Vector3f(-0.4f,-0.8f,0.1f));
model = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
model.center();
Node model2 = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
model2.center();
model2.setLocalTranslation(-30, 0, 0);
DirectionalLight light = new DirectionalLight();
light.setDirection((new Vector3f(0f,-1f, 0f)).normalize());
rootNode.addLight(light);
Box box = new Box(100, 1, 100);
Geometry floor = new Geometry("", box);
floor.setLocalTranslation(0f, -10f, 0f);
Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat1.setColor("Color", ColorRGBA.Blue);
floor.setMaterial(mat1);
rootNode.attachChild(model);
rootNode.attachChild(model2);
rootNode.attachChild(floor);
}
@Override
public void simpleUpdate(float tpf) {
model.lookAt(cam.getLocation(),Vector3f.UNIT_Y);
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
[/java]
At start you will clearly see what I mean.
may be this is what you want, it will make the character look at position of cam, but wont rotate himself to look into cam → wont lie on the floor
model.lookAt(cam.getLocation().setY(0), Vector3f.UNIT_Y);
but by me when I use it somehow I cant move the cam up and down anymore.
The vector needs to be the up vector of the base rotation you want to modify.
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:math_for_dummies
@xieu90
you can do this instead maybe:
model.lookAt(cam.getLocation().clone().setY(0), Vector3f.UNIT_Y);
But rather listen to what Normen says I suck at Vector math
@jatheron
I also suck at Vector math
but the line you gave me worked ^^
somewhere I heard that we shouldnt use clone, since it will make a new object and with a lot of object it will make the game slow. well but at least it works
@miki100
try to use the code jatheron gave us, you wanted it like that, right ?
What you are doing with this line is basically remove any y-component from the vector which forces it to have an y-up vector, hence the supplied y-up vector works… Kind of inverse logic… Just wanted to tell you in case you still didn’t understand the lookAt method
xieu90 said:
somewhere I heard that we shouldnt use clone, since it will make a new object and with a lot of object it will make the game slow. well but at least it works
If you only use the values for a calculation or whatever, don't clone as it requires some operations that take time, if you do not clone when you change the values inside, you change the actual object you point at, in this case, the cameras position itself. Just remember to clone if and only if you change the values inside while you want to preserve the values in the original instance.
Thanks for explaining a bit more Normen. I know that the line I supplied that is working is not the way to do it.
But… how do you calculate the correct Up vector for the LookAt function to work?
I think I know where the problem is. model.lookAt(cam.getLocation().clone().setY(0), Vector3f.UNIT_Y); worked in that testcase, but in my project not. Here is how I am doing it in my project:
Main.java:
[java]
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.light.DirectionalLight;
import com.jme3.math.Quaternion;
import com.jme3.scene.shape.Box;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
public class Main extends SimpleApplication{
Node model;
Node enemy;
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
flyCam.setMoveSpeed(20f);
enemy=new Node();
cam.setRotation(new Quaternion(0.30f,-0.69f,0.42f,0.49f));
cam.setLocation(new Vector3f(13f,43f,6f));
cam.setAxes(cam.getLeft(), cam.getUp(), new Vector3f(-0.4f,-0.8f,0.1f));
robot a =new robot(cam,assetManager,0,0,0);enemy.attachChild(a);
robot b =new robot(cam,assetManager,50,0,0);enemy.attachChild(b);
Node model2 = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
model2.center();
model2.setLocalTranslation(-30, 0, 0);
DirectionalLight light = new DirectionalLight();
light.setDirection((new Vector3f(0f,-1f, 0f)).normalize());
rootNode.addLight(light);
Box box = new Box(100, 1, 100);
Geometry floor = new Geometry("building", box);
floor.setLocalTranslation(0f, -10f, 0f);
Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat1.setColor("Color", ColorRGBA.Blue);
floor.setMaterial(mat1);
rootNode.attachChild(enemy);
rootNode.attachChild(model2);
rootNode.attachChild(floor);
}
@Override
public void simpleUpdate(float tpf) {
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
[/java]
robot.java:
[java]package mygame;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;import com.jme3.renderer.Camera;
import com.jme3.asset.AssetManager;
public class robot extends Node {
private Camera cam;
public robot(Camera came,AssetManager am,float x, float y, float z){
cam=came;
Node model = (Node) am.loadModel("Models/Oto/Oto.mesh.xml");
model.center();
model.setUserData("hp", 5);model.addControl(new mygame.robot_ctrl(this));
this.setLocalTranslation(x, y-5, z);
this.attachChild(model);
}
public void up(float tpf){
this.lookAt(cam.getLocation().clone().setY(0),Vector3f.UNIT_Y);
}
}
[/java]
robot_ctrl.java:
[java]package mygame;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
public class robot_ctrl extends AbstractControl{
private mygame.robot co;
public robot_ctrl(mygame.robot co) {
this.co = co;
}
@Override
protected void controlUpdate(float tpf) {
this.co.up(tpf);
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
// nothing to do
}
@Override
public Control cloneForSpatial(Spatial newSpatial) {
robot_ctrl control = new robot_ctrl(co);
control.setSpatial(newSpatial);
control.setEnabled(isEnabled());
return control;
}
}
[/java]
I hope that somebody will know the solution.
jatheron said:
But... how do you calculate the correct Up vector for the LookAt function to work?
By multiplying a 0,1,0 vector with the base rotation.
Sorry Normen, my brain is too small to understand the LookAt function. I need to study Vector math a lot more before I will understand any of this
@Miki100
I had a look at how Normen fixed the tilting bit in MonkeyZone and implemented it into your small testcase and it seems to work although this is not using LookAt the same way as before:
[java]
Vector3f tempRot=new Vector3f(0,0,0);
@Override
public void simpleUpdate(float tpf) {
model.getLocalRotation().lookAt(tempRot.set(cam.getDirection()).multLocal(1, 0, 1), Vector3f.UNIT_Y);
model.setLocalRotation(model.getLocalRotation());
}
[/java]
I have no idea what he did here but it works with your small test case. Maybe it works in your game as well?
Cheers