setUserData()

How do I use the setUserData method to give an enemy health.?
So say if the enemy was a blue cube geom, would you do geom.setUserData(“AnyRandomName”, 100); or do I create a node and do enemyCubeNode.setUserData(“AnyRandomName”, 100); to set the health to 100?

Also if anyone can give me a link to the a documentation of the method that would also be great!

Thanks!

You would do the second version

You would create a node then simply do

thisNode.setUserData(“StringName”, dataValue)

@BigBob said: You would do the second version

You would create a node then simply do

thisNode.setUserData(“StringName”, dataValue)

While we’re on the topic, the method is setup using T extends blah blah… but when you go to retrieve the data, you still have to cast it back to it’s original data type (unless I am doing something terribly wrong). Why not just use Object at this point?

1 Like

Thanks for the quick replies. So if I am correct, dataValue can be a variable and Index is basically the name.

Here’s the link to the JavaDoc, in case you still need it:

Spatial.setUserData

@t0neg0d said: While we're on the topic, the method is setup using T extends blah blah... but when you go to retrieve the data, you still have to cast it back to it's original data type (unless I am doing something terribly wrong). Why not just use Object at this point?

You shouldn’t have to cast it. That’s the point of the T bit. Java will infer the type based on what you are assigning it to.

You only need to cast when that’s ambiguous. (And sometimes javac thinks method arguments are ambiguous.)

Edit addendum: one must also be aware of autoboxing. So for primitives you have to use the non-primitive types or you will have to cast (and risk the NPE there).

One way:
[java]
Integer myInt = geom.getUserData(“SomeValue”);
[/java]

The other way:
[java]
int myInd = (Integer)geom.getUserData(“SomeValue”);
[/java]

@kevin.shen18 said: How do I use the setUserData method to give an enemy health.? So say if the enemy was a blue cube geom, would you do geom.setUserData("AnyRandomName", 100); or do I create a node and do enemyCubeNode.setUserData("AnyRandomName", 100); to set the health to 100?

Also if anyone can give me a link to the a documentation of the method that would also be great!

Thanks!

It actually doesn’t matter. Either will work fine and it just depends on your needs. No reason to create an extra node unless you need it for some other reason.

@pspeed said: You shouldn't have to cast it. That's the point of the T bit. Java will infer the type based on what you are assigning it to.

You only need to cast when that’s ambiguous. (And sometimes javac thinks method arguments are ambiguous.)

Edit addendum: one must also be aware of autoboxing. So for primitives you have to use the non-primitive types or you will have to cast (and risk the NPE there).

One way:
[java]
Integer myInt = geom.getUserData(“SomeValue”);
[/java]

The other way:
[java]
int myInd = (Integer)geom.getUserData(“SomeValue”);
[/java]

I ran into issues after saving/loading a Node. I just started playing around with this, so likely it is something I did wrong, however… I couldn’t get a String value back without casting it as a String. Has to be something I’ve done wrong.

Oh also, a bit off topic, but is there a way to delay something. Is there a delay method provided my jmonkey? Say when an enemy is moving I need it to wait one second between each movement.

In the update() method you get the float tpf. It is the time each frame is displayed and you should work with that. You could for example do something like this:

[java]//Import, class, etc.
private float time = 0;
//methods etc.
@Override
public void update(float tpf) {
time += tpf;
if(time >= 1) {
//move enemy
time = 0;
}
}[/java]

Thanks for the reply! What I’m trying to do is basically making a cube move along the Z axis with a one sec delay between every move. It’s going to be in a control class.

Thank you mathiajs! It works.

What if I want the delay to be longer? Like what would I do for two seconds. Sorry if these questions are a bit nooby. I have java experience but just not video game development experience.

@kevin.shen18

If using the tick loop the amount of ticks passing will be relative to the time of the machine you are on. For example a delay 100 ticks on and android device will be equal to about 1000 ticks on a regular pc.

If you are looking for a truely 2 second delay, using the system time (which has its own issues) is a good way to go.

So say you’re moving your enemy. You would have to give each enemy a last moved time (in the form of user data I assume), and a list of enemies to iterate on,(assuming you have more than one enemy). I suggest adding each of your enemies to an enemy node if that is the case.

So here’s how I’d handle it. (not tested in the least)

[java]
@Override
public void update(float tpf) {

//Retrieve current time in seconds
Long currentTime = System.currentTimeMillis() / 1000L;

//Iterate over all your enemies
for(int i = 0; i < enemyNode.getChildren().size(); i++){

 //Retrieves the current enemy you're dealing with in the form of a node
 Node currentEnemy = enemyNode.getChildren().getChild(i);

  //Retrieves the enemies last moved time stored as user data
  Long lastMovedTime = currentEnemy.getUserData("lastMoved"));
  
  //Checks if the last moved time in seconds is greater than one
  if (currentTime - lastMovedTime > 1) {

     //Move the enemy however you want

     //Sets the enemy's lastMoved time to the currentTime as that is when he moved
     currentEnemy.getUserData("lastMoved" currentTime));

     }
  }
}

[/java]

I hope this helps

Your enemy would have the data of a last moved time in the form of a userData called “lastMoved” and the enemy itself added to an “enemyNode” in the example above.

1 Like