[SOLVED] NPC looking at FP character

Hello,

I’ve been looking for anything to help my NPC rotate in the direction of my first person character.
And I’ve found examples but its costing my hours of my day. Does anyone have a legit example of an NPC setWalkDirection and setViewDirection code for Artificial Intellligence.

I’ll post my code in just a second. I did this last night but nothing came of it. Just give me a few minutes.

please I’m freakin desperate. I’ve practiced butt loads of tutorials and No I haven’t even got started on fps tutorials. But technically the only problem I’m having thus far is enemy location and rotation to the player. can someone help me. I’ve been typing examples and code all day and I’ve tried several examples. Nothing comes from it.


import com.jme3.app.SimpleApplication;
import com.jme3.scene.Geometry;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.scene.shape.Sphere;
import com.jme3.math.Vector3f;
import com.jme3.math.ColorRGBA;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.material.Material;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.controls.ActionListener;
import com.jme3.light.AmbientLight;
import com.jme3.scene.CameraNode;
import com.jme3.scene.control.CameraControl.ControlDirection;

public class Practice extends SimpleApplication implements ActionListener{
    private CameraNode camNode;
    private CapsuleCollisionShape capsuleShape;
    private Geometry sphereGeom, enemyGeom, groundGeom;
    private RigidBodyControl landscape, enemyControl;
    private CharacterControl playerControl, capShape;
    private BulletAppState bulletAppState;
    private Vector3f camDir, camLeft, dir;
    private Node sphere, enemy, groundNode;
    private Vector3f walkDirection = new Vector3f();
    boolean up,down,left,right=false;
    public static void main(String[]args){
        Practice p = new Practice();
        p.start();
    }
    public void simpleInitApp(){
        bulletAppState = new BulletAppState();
        stateManager.attach(bulletAppState);
        
        groundNode = (Node)assetManager.loadModel("Scenes/Practice/HomeBedroomFinal.scene");
        groundNode.setLocalScale(5f);
        rootNode.attachChild(groundNode);
        
        CollisionShape collisionShape = CollisionShapeFactory.createMeshShape((Node) groundNode);
        landscape = new RigidBodyControl(collisionShape, 0);
        groundNode.addControl(landscape);
        landscape.setPhysicsLocation(new Vector3f(0,0,-1));
        bulletAppState.getPhysicsSpace().add(landscape);
        
        sphereGeom = new Geometry("player", new Sphere(3,3,1));
        Material sphereMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        sphereGeom.setMaterial(sphereMat);
        sphereMat.setColor("Color", ColorRGBA.Blue);
        sphere = new Node("playerNode");
        sphere.attachChild(sphereGeom);
        rootNode.attachChild(sphere);
        
        SphereCollisionShape sphereShape = new SphereCollisionShape(1);
        playerControl = new CharacterControl(sphereShape, 0.05f);
        sphere.addControl(playerControl);
        playerControl.setPhysicsLocation(new Vector3f(3,3,3));
        bulletAppState.getPhysicsSpace().add(playerControl);
        
        enemy = (Node)assetManager.loadModel("Interface/PracticeInterface/ghoul.mesh.xml");
        Material matEnemy = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        enemy.setMaterial(matEnemy);
        matEnemy.setColor("Color", ColorRGBA.Red);
        
        capsuleShape = new CapsuleCollisionShape(.35f, .85f, 1);
        capShape = new CharacterControl(capsuleShape, 0.5f);
        enemy.addControl(capShape);
        capShape.setPhysicsLocation(new Vector3f(-3, 6, 3));
        rootNode.attachChild(enemy);
        bulletAppState.getPhysicsSpace().add(capShape);
        
        setUpInput();
        setUpLight();
    }
    private void setUpLight(){
        AmbientLight al = new AmbientLight();
        al.setColor(ColorRGBA.Orange);
        rootNode.addLight(al);
    }
    private void setUpInput(){
        inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_UP));
        inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN));
        inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_LEFT));
        inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_RIGHT));
        inputManager.addMapping("follow", new KeyTrigger(KeyInput.KEY_SPACE));
        inputManager.addListener(this, "up");
        inputManager.addListener(this, "down");
        inputManager.addListener(this, "left");
        inputManager.addListener(this, "right");
        inputManager.addListener(this, "follow");
        
        
    }
    public void onAction(String name, boolean isPressed, float tpf){
        if(name.equals("up")){
            if(isPressed){
                up=true;
            }else{down=false;}
        }else if(name.equals("down")){
            if(isPressed){
                down=true;
            }else{up=false;}
        }else if(name.equals("left")){
            if(isPressed){
                left=true;
            }else{right=false;}
        }else if(name.equals("right")){
            if(isPressed){
                right=true;
            }else{left=false;}
        }else if(name.equals("follow")){
            if(isPressed){
               dir = sphere.getWorldTranslation().subtract(enemy.getWorldTranslation());
        dir.normalizeLocal();
        capShape.setViewDirection(dir);
        Vector3f playerLocation = sphere.getWorldTranslation();
        Vector3f npcLocation = enemy.getWorldTranslation();
        Vector3f offset = playerLocation.subtract(npcLocation);
        capShape.setWalkDirection(dir.mult(0.2f));
            }
        }
    }
    public void simpleUpdate(float tpf){
        camLeft = new Vector3f();
        camDir = new Vector3f();
        camLeft.set(cam.getLeft()).normalizeLocal().mult(0.4f);
        camDir.set(cam.getDirection()).normalizeLocal().mult(0.6f);
        walkDirection.set(0,0,0);
        if(up){
            walkDirection.addLocal(camDir);
        }
        if(down){
            walkDirection.addLocal(camDir.negate());
        }
        if(left){
            walkDirection.addLocal(camLeft);
        }
        if(right){
            walkDirection.addLocal(camLeft.negate());
        }
        
        playerControl.setWalkDirection(walkDirection);
        cam.setLocation(playerControl.getPhysicsLocation());
        
        
    }
}

I don’t have follow code for enemy on this but. I’ve tried several of them including ones with setWalkDirection and getWorldTranslation

I have a serious question on this. getWorldTranslation is a method for objects and not collision based systems such as charactercontrol or rigidbodycontrol…

So…can a Node use getWorldTranslation and if so. Is it better to use this method with the player or npc’s geometry OR node???

:slight_smile:

Use

Vector3f dir = playerNode.getWorldTranslation().subtract(npcNode.getWorldTranslation());
dir.normalizeLocal();
npcControl.setViewDirection(dir);

Thank you very much. in fact I’m actually working on that now! :slight_smile:
and I’ll post the code after it works sir!

Just fixed it and I got rid of the sphere enemy and used the ghoul enemy from the GitHub FPS project!
The ghoul turns in the direction! I found out the problem. I had RigidBodyControl as the control for the enemy rather than CharacterControl. I’ve been meaning to look through that but didn’t give it much attention. Just a few days ago I made a tower, ground, and leaves particle emitter project. And I gave this same situation a go…But I used RigidBodyControl instead. Thanks Jmonkey Hub!

I did my last bit of work on the project I was doing. And I set the ghoul viewDirection and walkDirection methods and code inside of an else if statement inside the onAction method to test whether if I press space bar or not the ghoul will come after me…And it does! The code is posted above. Once again thank you jmonkey hub and its people. peace.

On another Note… use BetterCharacterControl instead of CharacterControl. It’s … better.

1 Like

I plan on studying the class before using BetterCharacterControl. .

I’m actually creating a FPS game with some school perks. Its still a working process. And I’ll post its code sometime this Christmas I hope. Thanks Robbi!