Hi, I am stuck in a very weird problem; I have created a basic scene with Babylonjs + react.
On the page I also have a dropdown that calls an API to get some data. As soon as I call the api, and fill some other drop downs; the rendered scene stops accepting any touch inputs.
Also, although the scene looks ok; but if I try to get any meshes from the scene, I get a null.
So it shows all the boxes / spheres etc; but I cannot manipulate them any more. I cannot create this on a playground since; this only happens when I call the API to load other dropdowns on the same page. If it helps I can create a github project for this.
Any pointers would help (unable to understand what might have gone wrong).
No errors in the console … just that when I try to remove the meshes from the scene to change it with data I got from the API … I am not able to change anything (since the meshes.length is zero)
I have a SceneRenderer (which instantiates babylon); then this component is included in other component that has the onSceneReady(); On this component I have other dropdowns to get the data from user interaction.
I think the issue is when useContext. I am using Mobx to observe any changes (instead of redux) and if anything in the context changes and this component has to update it makes the Scene non responsive and resets all the meshes etc. (although visually it still displays the canvas).
Would you want me to create a github project that just calls mobx to show my structure --very much in a bind to get this fixed ; any pointers would help.
If I were to hazard a guess what’s happening is you’re causing a VDOM diff which is making it reinstantiate the scene. There may be a second instance of Babylon underneath the one you already have. If you could create the Babylon instance as a singleton or wrap it inside a conditional render path that might fix the issue.
A Github project would be great so we could see the code.
On further experimentation; I found the issue is when I setState() on anything on the page; I can create a simple github project to show us what I mean.
So if I have a Canvas Component that is rendered, any time I do a setState on any other html component like a dropdown; the cavas stops the renderloop(). Will create a github project to show this; please let me know if you can think of anything
Sounds like you are creating a new scene and losing your render loop when props change. Make sure that you consider the render method is re-entrant. Look forward to your repo.
I have cleaned up most of my other code (mobx / api calls etc) – since I realize the issue is when I do setState (nothing to do with context etc). I can remove the components from mobx observers if you want.
On the page; the buttons add / clear will work also long as you don’t do anything with the select box; Once you do anything with the select; the touch will stop working and also the meshes.lenght will become zero; even though the page will show the Meshes.
(this is because of the setState() call).
So to reproduce; simply load the page and click on the select box and select an option.
It’s your useEffect - it will be called anytime what you have in the list of dependencies is called, which will call the method you are returning and it is disposing your scene.
Also, you can remove a bunch of libraries. You are using ‘@babylons’ and ‘babylonjs’ both, so probably just reference the @babylonjs ones. You can remove also react-babylonjs - it doesn’t look used. Also, you overwrite the onDispose of the scene directly, but think you would be better registering onDisposeObservable. Same some other interesting things, but look up the useEffect hook and how the dependencies list in turns determines
Many thanks for this! – I just changed the dependency to reactCanvas only (for now); it has started to work. I will see how to use OnDisposeObservable; that way I can at least console log to know when my scene is getting disposed.
Also, could you please comment on my thoughts below :- the reason I did not use your declarative react project was because;
a) my ignorance – will read up on this
b) my requirement was to handle the mouse moves very heavily
a) Some of the conditions were like – If a mesh is being picked and it collides with another mesh; I wanted to highlight both of them red;
b) I also wanted to hack the mouse move to allow the user to move in the y direction (so I can lift up objects) based on if the user click on alt + mousemove.
Basically it is a simple tetris like application that allows the user place objects like a jig-saw puzzle (so rotate and place in the available space) – kind of a riddle in 3-d (for kids).
My problem with the declarative react project was, I could not find a way to handle all mouse operations to make different conditions of rotate, collision, axis movements possible; with object highlighting.
I would be very happy to hear your thoughts on this, any pitfalls you foresee.
I wouldn’t encourage one way or the other. You might want to have a look at this project, which is a multi-player written declaratively and is turn based using blocks:
I built also a turn-based robot control game using redux-saga for state management. I wouldn’t encourage one way or the other. The mesh picked event could be handled with onPointerDownObservable perhaps and then state management to what the drag would do. You might want to have a look at declarative pointer drag behaviour to control moving in the y-direction only:
That can be done non-declaratively as well and may very well be easier to set the drag plane dynamically and imperatively. The thing with declarative is that it’s really easy to get started and then maybe you will hit a wall or you have kludges to push the state.
Looks like a great project are working on. Look forward to when you post a demo
The gizmo is really good as well - perhaps building that out as a component may help with your mouse interactions: https://doc.babylonjs.com/how_to/gizmo
Many thanks for this; I am currently looking at both santorni game and gizmo’s!; (both of these are gold mines for me).
If I ever get good at it I will definitely put my project in Github when it becomes a little presentable.
Will let you know as soon as I have something to show. (thanks again).