It never fails – the moment I ask for advice online I find the bug!
Posting this here for reference for others possibly using ecsy-babylon:
The ‘MeshSystem’ handles any additions, changes, or removals of mesh. The problem was the ‘changed’ query:
// This function runs every time a Mesh Component is changed (For example, by having a texture applied)
this.queries.mesh.changed.forEach((entity: Entity) => {
disposeObject(entity.getMutableComponent(Mesh)!); // This deletes the component!
this._updateMesh(entity, entity.getMutableComponent(Mesh)!);
});
// This creates an entirely new BABYLON.Mesh object
private _updateMesh(entity: Entity, mesh: Mesh) {
switch (mesh.type) {
case MeshTypes.Url:
mesh.url && BABYLON.SceneLoader.IsPluginForExtensionAvailable(this._fileExt(mesh.url)) ?
this._loadUrlMesh(entity, mesh, mesh.url) :
this._unsupportedMesh(entity, mesh);
break;
default:
mesh.object = (BABYLON.MeshBuilder as any)[`Create${mesh.type!}`].call(this, mesh.type!, mesh.options ? mesh.options : {}, getScene(this, mesh.scene));
this._updateMeshValue(mesh);
updateObjectsTransform(entity);
break;
}
}
So every time a mesh was changed (like by adding a texture), ecsy-babylon would delete that mesh and create a brand new one, without the texture applied. Oops!