addControl

Hi i have a problem with adding a control

 Node  jack22=(Node)assetManager.loadModel("Models/newJack2/newJack2.j3o");
   ((Geometry)((Node)jack22.getChild(0)).getChild(0)).getMaterial().setColor("Ambient",ColorRGBA.White);
            MyNode jack2 = new MyNode();
            jack2.attachChild(((Geometry)((Node)jack22.getChild(0)).getChild(0)));
   rootNode.attachChild(jack2);
   
            System.out.println(jack22.getChild(0).getControl(SkeletonControl.class));
   System.out.println(jack2.getControl(SkeletonControl.class));
   jack2.removeControl(SkeletonControl.class);
   System.out.println(jack2.getControl(SkeletonControl.class));
   jack2.removeControl(AnimControl.class);
  jack2.addControl((SkeletonControl) jack22.getChild(0).getControl(SkeletonControl.class));
 jack2.addControl(jack22.getChild(0).getControl(AnimControl.class));
 
  SkeletonControl skeletonControl2 = jack2./*getChild(0).*/getControl(SkeletonControl.class);
  jack2.setLocalTranslation(collisionResult.getClosestCollision().getContactPoint());
  jack2.getLocalTranslation().setY(collisionResult.getClosestCollision().getContactPoint().getY()+jack2.getLocalScale().getY()-0.15f);

java.lang.IllegalStateException: This control has already been added to a Spatial
at com.jme3.scene.control.AbstractControl.setSpatial(AbstractControl.java:60)
at com.jme3.animation.SkeletonControl.setSpatial(SkeletonControl.java:233)
at com.jme3.scene.Spatial.addControl(Spatial.java:769)
at mygame.Main$1.onAction(Main.java:73)
at com.jme3.input.InputManager.invokeActions(InputManager.java:169)
at com.jme3.input.InputManager.onMouseButtonEventQueued(InputManager.java:446)
at com.jme3.input.InputManager.processQueue(InputManager.java:864)
at com.jme3.input.InputManager.update(InputManager.java:914)
at com.jme3.app.LegacyApplication.update(LegacyApplication.java:725)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:227)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:197)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:232)
at java.lang.Thread.run(Thread.java:748)

I think im deleting it wrong or adding it wrong

There are many controls that are not setup to be reused like this. It’s also extremely rare that this is even a good idea.

You may want to take a step back and explain why you are doing this very super strange thing.

Oh well :slight_smile: i do import a blender model ,and it is in a node ,while i need it to go in MyNode
And i dont want to put a Node node in MyNode myNode (couse it can mess up collision on ray’s,it may collide to a box contaning my geom and not geoms surface) So i want to take geom from Node and put it in MyNode (it do stuff i need it to do that a Node cant)
And i dont know if its even possible to transform Node (father) in MyNode (child)

seems this might be a solution ,but still may contain bugs

            jack22.getChild(0).getControl(SkeletonControl.class).setSpatial(null);
            jack2.addControl(jack22.getChild(0).getControl(SkeletonControl.class));
            jack22.getChild(0).removeControl(SkeletonControl.class);

If any 1 know anything ,i would really like to know it as well :slight_smile:

Damn bones are null … eeeh

So, this is all because you find addressing the child slightly inconvenient?

Emmm this is couse i need a Node node to be MyNode myNode;

MyNode have methods and values Node has not, thats why. What i need is an Object of Class Node to become of Class MyNode that is a child ,but i dont know how to do

Ah, well… you are down a path we don’t recommend. We specifically recommend against extending Node or Spatial for your game objects.

So you will kind of be on your own for support because there are very very few good reasons to do this in user code and you will constantly have issues.

Edit: probably what you want is a custom control instead of extending Node.

Well i use MyNode to carry info of my units, and i dont know where alse could i store them … damn … do you think doing the same thing to Geometry would be better? like MyGeometry and not MyNode ?

Mistake 1 is thinking of Spatials as game objects. They are the visuals and not the game objects.

Mistake 2 is extending Node instead of creating a custom control to do your unrecommended merging of Spatial and game object. At least this approach will last longer before it all crumbles under its own weight.

When you get to the point where things are too hard to add and so on and decide to rewrite it all from scratch, you can always address problem 1.

I do not give spatials
int hp = 10;

I create UnitStats unitStats = new UnitStats() ;
unitStats.setHp(10);
and then say
spatial setUnitStats(unitStats);

if i dont tie visual and stats,when i get shoot visual how could i change the right stats ?

What i say is I have a virtual non phisical data ,but if phisical objects have no relations to them ,how could things i see correspond to changes to virtual data

Before you piss paul off I think I might ask, just how much of the wiki have you read?

All this is covered there. You cannot do the beginner tutorials and expect to write a game. They are designed to get you acquainted with the engine prior to your reading the rest of the wiki.

Its setup to be read in order like a book.

You have set yourself up for guaranteed failure by not doing so.

Emm i’ve read all F1 stuff,is that what you intend?

Assuming that this is the code inside of your “MyNode” class, then I would instead suggest you don’t extend Node, but add a local Node variable in your class with a getNode() method for when you need to access it ouside of that class. This way, your AI code & logic will be storing a reference to the visualization, rather than extending the Node and including the visual aspect as part of the logic

Gave a quik read to intermediate and advance ,nothing say what i was treating

Im not sure im understanding what you say. Right now i have a node that has a geometry(soldiers body inside)
(I use node couse it is composed of different geoms and other stuff)
I say node move with the body forward 10 cm and look if there any enemy node close to you
if yes run anim hit and ray cast from sword
if you hit ,get geom ,get parent node – then take virtualClassStats object from node like “node.getvirtualClassStats”
soo virtualClassStats.reduceHp(hitForce);
Now i can put virtualClassStats in geom (may be) or could put it in node,but i cant finde any other way or place to put it, and i cant understand what you intend as well sorry :slight_smile: ,could you pleas explain better :slight_smile: ?

Yeah I didn’t do a great job of explaining what I meant in my last post. I’m assuming that when you say “virtualClassStats” that your talking about the Player / NPC information like health, location, and pathing information.

Here’s a snippet of my “Agent” class that handles all of the logic about the player’s stats, pathing, attacking, etc. It sounds like this is similar to your “myNode” class except it doesn’t extend the node. Instead it stores a node so it can still do collisions and move the node when necessary. But in this case, if the node happened to be null then nothing bad happens; the node that represents my player simply doesn’t get moved if its null.

public class Agent {

public static enum AgentType{ 
    MainPlayer,
    Npc,
    Player,
    Menu
}

public int team;
public Agent target;
public AgentNav agentNav;

public float magic, defense, agility, strength, health, maxHealth, mana, maxMana;

public float getMaxHealth(){ return maxHealth; }
//get methods for the rest of the stats...

public Vector3f agentLocation;

public Node agentNode;
public Node getAgentNode(){ return agentNode; }


public Agent(Spatial playerModel, Vector3f spawn){
      //init for this agent 

      agentLocation = spawn;

      //visualization for the client
      agentNode= new Node();
      agentNode.attachChild(playerModel);
      agentNode.setLocalTranslation(agentLocation);
      app.getRootNode().attachChild(agentNode);

      
} 

...
...

public void moveAgent(Vector3f direction){
        agentLocation.addLocal(direction); //non-visual representation of the agents location.

 }

//example of your method for reducing hp working with this class
 public void reduceHp(float amount){
      health -= amount;
      if(health <= 0){   //agent dies. 
           if(agentNode != null){ //change the visualization on clients
                  app.getRootNode().detachChild(agentNode);
            }
           //rest of agent cleanup 
     }
      
 }

So if you don’t extend node, then you will create less limitations for yourself and can still use your own class to check things like collision with the stored node and any of its children.

1 Like