I ran into something weird today and I wanted to check and see if my idea for a fix is good or not.
I was experimenting with the framing behavior of ArcRotateCamera and tweaked the official example. I changed it to move the box and delay setting the target mesh. In my example when the target mesh is set after three seconds the camera’s position pops: https://www.babylonjs-playground.com/#GZY2YB#2
I debugged things and when camera.setTarget(box) is called it immediately replaces the target position for the camera with the position of the box (line 880ish of Cameras\babylon.arcRotateCamera.ts). This prevents the framing behavior from actually animating the camera’s target position since it just got set to where it would end up at the end of the animation.
I made this change to fix the camera position pop: Fixed issue where ArcRotateCamera ignored framing behavior in setTarget. · nathankmiller/Babylon.js@211034b · GitHub
From reading the docs and looking at the code it seems that in the case where you set the target to a mesh that you want the framing behavior to drive the camera, so you shouldn’t immediately set the camera’s target. This change makes camera.setTarget() behave the same way as camera.framingBehavior.zoomOnMesh() when a target position animation is required.
I don’t know if updating _targetBoundingCenter and _targetHost but not _target is a problem. After updating those two values onMeshTargetChangedObservable is called, which immediately results in a call to setTarget() again with a Vector3 that essentially erases the temporary weird state.
After the change if I compare the results of camera.setTarget(box) with camera.framingBehavior.zoomOnMesh(box) they both look the same. The camera does take a path to focus on the object that is unexpected, though. That appears to be due to the code in ArcRotateCamera.rebuildAnglesAndRadius() that gets called each time the target changes.