I am wondering the correct way to go about using an entity system to create basically a boolean. Currently I am using a empty component called “OnABoat” that I add when my player entity is on a boat and then remove when I am no longer on a boat. I seem to be getting a weird behavior when I do it this way which I am a bit confused about. I have added OnABoat.class to the serializer because I need it for visualization on the client.
First time I am on a boat, seems fine:
20:07:55,518 INFO [MessageDebugger] Received:EntityDataMessage[3, [ComponentData[EntityId[2], [[OnABoat]]]]]
I remove the entity and put it back on later … the message doubles
20:08:37,408 INFO [MessageDebugger] Received:EntityDataMessage[3, [ComponentData[EntityId[2], [[OnABoat]]]]]
20:08:37,408 INFO [MessageDebugger] Received:EntityDataMessage[4, [ComponentData[EntityId[2], [[OnABoat]]]]]
etc etc, it continues to add a message every time I remove and re-add the component.
Is this expected behavior?
ed.removeComponent(entityId, OnABoat.class);
ed.setComponent(entityId, new OnABoat());
Makes me wonder if you are creating a new EntitySet each time and then not releasing an old one. Hard to say without knowing what you are doing with OnABoat on the client.
There is no reason for it to be sent more than once unless requested more than once.
EntitySet es;
public Mob(Entity entity) {
this.entity = entity;
this.spatial = createModel(entity);
BodyPosition bodyPos = entity.get(BodyPosition.class);
// BodyPosition requires special management to make
// sure all instances of BodyPosition are sharing the same
// thread-safe history buffer. Everywhere it's used, it should
// be 'initialized'.
bodyPos.initialize(entity.getId(), 12);
buffer = bodyPos.getBuffer();
// Starts invisible until we know otherwise
resetVisibility();
int tankType = ed.getStrings().getStringId("tank", false);
ComponentFilter filter = Filters.fieldEquals(ObjectType.class, "type", tankType);
es = ed.getEntities(filter, OnABoat.class);
}
public void updateSpatial(long time) {
// Look back in the brief history that we've kept and
// pull an interpolated value. To do this, we grab the
// span of time that contains the time we want. PositionTransition
// represents a starting and an ending pos+rot over a span of time.
PositionTransition trans = buffer.getTransition(time);
if (trans != null) {
//log.info("UpdatingEntityId: " + entity.getId());
//log.info("Entity: " + entity.toString());
spatial.setLocalTranslation(trans.getPosition(time, true));
spatial.setLocalRotation(trans.getRotation(time, true));
setVisible(trans.getVisibility(time));
if (es.applyChanges()) {
Set<Entity> removedEntities = es.getRemovedEntities();
Set<Entity> addedEntities = es.getAddedEntities();
if (!removedEntities.isEmpty()) {
if (spatial.getName().contains("tank")) {
for (Entity ent : removedEntities) {
((Node) spatial).getChild("Models/BoatMesh.blend").setCullHint(Spatial.CullHint.Always);
}
}
}
if (!addedEntities.isEmpty()) {
if (spatial.getName().contains("tank")) {
for (Entity ent : addedEntities) {
((Node) spatial).getChild("Models/BoatMesh.blend").setCullHint(Spatial.CullHint.Inherit);
}
}
}
}
}
}
I switched these sections of code over to an AppState and now it works as expected. Thank you for your help pspeed. I was having a derp moment when I wrote that code originally lol.