Hi,
I have a question. I want to use in android app (babylonjs react native)
upload two glb models async.
When i do it one after the other async, i get:
gallery_b4.glb : one instance
Xbot.glb : two instance with two different id (avatarMesh.uniqueId)
If the model Xbot after the gallery is loaded (see code), then I get :
gallery_b4.glb : one instance
Xbot.glb: one instance with id and second is undefined.
Why?
useEffect(() => {
const modelsUrl = "app:///models/";
const glbFile = "gallery/gallery_b4.glb";
SceneLoader.ImportMeshAsync(null, modelsUrl, glbFile, scene).then(result => {
const mesh = result.meshes[0];
console.log("gallery_b4.glb is loaded: " + mesh.uniqueId);
const glbAvatarFile = "avatare/Xbot.glb";
SceneLoader.ImportMeshAsync(null, modelsUrl, glbAvatarFile, scene).then(resultAvatar => {
const avatarMesh = resultAvatar.meshes[0] as Mesh;
console.log("Xbot avatar is loaded: " + avatarMesh.uniqueId);
});
});
..........
}, [engine]);
I use mesh like this later:
It works:
var avatarMesh = scene.getTransformNodeByName("Xbot");
if(avatarMesh) {
console.log("avatarMesh.position.x: " + avatarMesh.position.x);
}
could it be because your engine is recreated somehow ???
cc @ryantrem
Two instances of Xbot are created at the very first start.
Strange.
from others gallery_b4.glb not, only one
If ‘engine’ is always available - what about an empty dependency array in useEffect? That will happen extractly once - or are you changing engines?
Ps: can you share a repro?
I’m assuming there is a const engine = useEngine()
prior to the useEffect
in your code snippet above. useEngine()
initially returns null
, and later returns a value (because engine creation is asynchronous in Babylon React Native due to the back and forth communication between native and JS, though we may be able to fix this in the future with TurboModules). Given this and that your callback passed to useEffect
does not check if engine
is non-null, I would expect that whole block of code to run twice (both models load twice). You can check with a debugger or with some console.log
debugging. I would expect it to work the way you want if you change it to:
useEffect(() => {
if (engine) {
const modelsUrl = "app:///models/";
const glbFile = "gallery/gallery_b4.glb";
SceneLoader.ImportMeshAsync(null, modelsUrl, glbFile, scene).then(result => {
const mesh = result.meshes[0];
console.log("gallery_b4.glb is loaded: " + mesh.uniqueId);
const glbAvatarFile = "avatare/Xbot.glb";
SceneLoader.ImportMeshAsync(null, modelsUrl, glbAvatarFile, scene).then(resultAvatar => {
const avatarMesh = resultAvatar.meshes[0] as Mesh;
console.log("Xbot avatar is loaded: " + avatarMesh.uniqueId);
});
});
..........
}
}, [engine]);
3 Likes
Sorry, I have to correct myself.
My code was already like this:
useEffect(() => {
if (engine) {
const scene = new Scene(engine);
setScene(scene);
At the first start, give one and one instance.
After the refresh, one and two from XBot.
Can you post the full code? The setScene
will cause a React re-render, but it should not trigger the useEffect
a second time. Also, the full console.log listing to track the order of promises completing.
Hello @igorroman777 checking in, are you still having an issue?