Problem with controlling of objects

    for (int i = 0; i < enemyTrooperNode.getQuantity(); i++) {
float distance = enemyNode.getChild(i).getLocalTranslation().distance(characterNode.getWorldTranslation());

//ENEMY - DIRECTION
                        
enemyWalkDirection.set(0, 0, 0);
Vector3f currentLookAtLoc = new Vector3f(0, 0, 0);       

enemy.lookAt(characterNode.getLocalTranslation(), Vector3f.UNIT_Y);                                             // rotate enemy spatial towards player - all enemies were init in loop using the same spatial - only name and location were modified
enemyNode.getChild(i).lookAt(characterNode.getLocalTranslation(), Vector3f.UNIT_Y);                         // rotate enemy node towards player       
Vector3f enemyForwardDir = enemyNode.getChild(i).getLocalRotation().mult(Vector3f.UNIT_Z);          
         
 // REDUCE DISTANCE     
 if (distance < 27 && distance > 20) {    
  enemyWalkDirection.addLocal(enemyForwardDir.mult(3f));
  }
}

I have a couple enemies generated in the loop. All of them with the same spatial with only changed position of node in the tree, location and name changed by itteration. Code as above makes the only one of enemies behaving as should. Other ones only stands - despite they have the same spatial model “enemy” which should lookAt character. Other functionalities like shooting by them and dying works fine. Thanks for help.

I can’t see the part where you reference “enemy” - but it appears to me that the “enemy” object reference is only pointing to the first one. If you post that part of the code I’d be able to tell you for sure.

   public void EnemyShape(Vector3f loc1, int nodeTag) {   enemyTrooperNode = new Node("ZTrooper" + nodeTag + "| ");
    enemy = assetManager.loadModel("Models/playerExperyment/playerExperyment.j3o");
    CollisionShape colShape1 = CollisionShapeFactory.createDynamicMeshShape(enemy);
    enemyTrooperNode.attachChild(enemy);
    physicsCharacterEnemy = new BetterCharacterControl(0.3f, 2.5f, 20f);
    enemyTrooperNode.setLocalTranslation(loc1);
   
    enemyTrooperNode.addControl(physicsCharacterEnemy);
    enemyNode.attachChildAt(enemyTrooperNode, nodeTag);

    bulletAppState.getPhysicsSpace().add(physicsCharacterEnemy);
}

Here you go

In the loop of the first post, the enemy object is never changed. it is always just “enemy” and not enemy[index] which means that it will not change in your loop. Which to me is why only one of them is doing whatever is in that loop.

I am afraid I can’t iterate variables name dynamicly ? Any suggest ? - java reflection ?

When you create your enemies put them in an array or list, so you can call enemy[i] or enemy.get(i).

So far as I can see from the code, there is only one enemy object, and that enemy object is being referenced in the loop every iteration. You iterate over the count of enemies, but don’t set the enemy object to that enemy.

Your EnemyShape method should probably return the spatial instead of setting a field that you reference iteratively in a loop. It will always be referencing the last enemy that was created when you called the EnemShape method.

Something like this off the top of my head.

Spatial[] enemies = new Spatial[enemyCount];

// create the enemies and keep a reference of them....
for (int i = 0; i < enemyCount; i++) {
enemies[i] = EnemyShape(...);
}

// do something with the enemies...
for (int i = 0; i < enemyCount; i++) {
Spatial enemy = enemies[i];
// now do your lookAt, etc...
enemy.lookAt(...);
}

Thats good. LookAt magically is working. Only DISTANCE REDUCING is still with no effect… seems like the location update doesnt work.

ArrayList enemyForwardDir = new ArrayList();

            if (enemyForwardDir.isEmpty()) {

            for (int in = 0; in < enemyTrooperNode.getQuantity(); in++) {
                enemyForwardDir.add(enemies.get(in).getLocalRotation().mult(Vector3f.UNIT_Z));
            } for (int i = 0; i < enemyTrooperNode.getQuantity(); i++) { //ENEMY IN RANGE ? ----------------------------
        float distance = enemiesNode.get(i).getLocalTranslation().distance(characterNode.getWorldTranslation());

//ENEMY DIRECTIONING
enemyWalkDirection.set(0, 0, 0);
enemies.get(i).lookAt(characterNode.getLocalTranslation(), Vector3f.UNIT_Y); // rotate enemy spatial towards player
enemiesNode.get(i).lookAt(characterNode.getLocalTranslation(), Vector3f.UNIT_Y); // rotate enemy node towards player
if (distance < 27 && distance > 20) {
enemyWalkDirection.addLocal(enemyForwardDir.get(i).mult(3f)); // Reduce distance
}
}
physicsCharacterEnemy.setWalkDirection(enemyWalkDirection);

Ok. I have something like this. Each enemy is lookingAt, shootin, dying but not walking… Why there is no update for position of enemies but only for the one of them ?

Maybe you are reusing the same enemyWalkDirection instance over and over?

Edit: I mean, it shouldn’t matter but I don’t know how physicsCharacterEnemy is written (even if it’s a JME class, I’m not too detailed on the physics controls and stuff.)

Another odd behaving of models… If I am moving player character ( right side one ) towards enemies, then they are not keeping the vertical position and skewing - and shooting over the player character. It happens only when I am standing infront of numberous enemies - not infront of single one. I have still problem that only last one enemy from array is moving despite the all of them recognize they should move ( state displayed on conslole )… maybe it is related ?

position

Yep, probably. You are either corrupting the JME constants or reusing things you shouldn’t be. That’s in code we can’t see, I guess.

  ArrayList<Spatial> enemies = new ArrayList<Spatial>();
ArrayList<Node> enemiesNode = new ArrayList<Node>();
ArrayList<Vector3f> enemiesLoc = new ArrayList<Vector3f>();

public void initEnemy() {

    for (int i = 0; i < 7; i++) {
        Random r = new Random();
        float a = r.nextInt(20) - (30);
        float b = r.nextInt(50) - (25);
        Vector3f loc1 = new Vector3f(b, 0.4f, a);
        int nodeTag = i;
        enemies.add(assetManager.loadModel("Models/playerExperyment/playerExperyment.j3o"));
        enemiesNode.add(new Node("enemy|" + nodeTag));
        enemiesLoc.add(loc1);

        EnemyShape( nodeTag);
    }
}

public void EnemyShape( int nodeTag) {

    enemyNode = enemiesNode.get(nodeTag);
    enemy = enemies.get(nodeTag);

    physicsCharacterEnemy = new BetterCharacterControl(0.3f, 2.5f, 80f);
    enemyNode.setLocalTranslation(enemiesLoc.get(nodeTag));
    enemyNode.addControl(physicsCharacterEnemy);
    CollisionShape colShape1 = CollisionShapeFactory.createDynamicMeshShape(enemy);
   
    enemyNode.attachChild(enemy);
    rootNode.attachChild(enemyNode);

}

// MAIN LOOP--------------------
@Override
public void simpleUpdate(float tpf) {

    for (int i = 0; i < enemies.size(); i++) {
        enemyWalkDirection.set(0, 0, 0);

        float distance1 = enemiesNode.get(i).getLocalTranslation().distance(characterNode.getWorldTranslation());
        enemies.get(i).lookAt(characterNode.getLocalTranslation(), (Vector3f.UNIT_Y)); // SPATIAL - LOOK AT
        enemiesNode.get(i).lookAt(characterNode.getLocalTranslation(), (Vector3f.UNIT_Y));

       Vector3f enemyForwardDir = enemiesNode.get(i).getWorldRotation().mult(Vector3f.UNIT_Z).clone(); // przyrost lokalny na Z - do ruchu
       Vector3f enemyLeftDir = enemiesNode.get(i).getWorldRotation().mult(Vector3f.UNIT_X).clone(); // // przyrost lokalny na X - do zmiany kierunku

     
        if (distance1 < 27 && distance1 > 20) { // REDUCE DISTANCE

            enemyWalkDirection.addLocal(enemyForwardDir.mult(3f));// MOVE
            System.out.println("enemiesNode: " + enemiesNode.get(i) + " Idzie: " + distance1);
            
        }
        physicsCharacterEnemy.setWalkDirection(enemyWalkDirection);
        physicsCharacterEnemy.setViewDirection(enemyViewDirection);
        System.out.println("enemiesNode: " + enemiesNode.get(i).getName() + " COORDS: " + enemiesNode.get(i).getLocalTranslation() + "enemyForwardDir: " + enemyForwardDir);

Right. After removing all of other code I see the issue more clearly I hope. I see the update is only on last added enemy - seems the physical state is considered for the enemy. Anybody know how to deal with it?

I feel like we went through this when I responded the first time… Maybe have a read through it again.

Sorry. You are right. Due to small mistake in notation I were unable to create an array.

1 Like