pcace
August 8, 2023, 11:17am
1
Hi there, i am trying to get the camera Position in React in a stateful variable, but have the problem, that i (i think) the 60fps from babylon are too fast to get this in the state variable? so what i see is that the performance is extremely bad with this line:
setCameraPosition([camera.position.x, camera.position.y]);
thsi is the snipped of the code:
const camera = scene?.cameras[0]
const prevPositionRef = useRef<Nullable<Vector3>>(null);
const [cameraPosition, setCameraPosition] = useState<number[]>([0,0])
useEffect(() => {
if (camera) {
const onBeforeRender = () => {
if (!prevPositionRef.current || !prevPositionRef.current.equals(camera.position)) {
setCameraPosition([camera.position.x, camera.position.y]);
prevPositionRef.current = camera.position.clone();
}
};
camera.onAfterCheckInputsObservable.add(onBeforeRender);
return () => {
camera.onAfterCheckInputsObservable.removeCallback(onBeforeRender);
};
}
}, [camera]);
console.log(prevPositionRef.current)
what am i doing wrong here?
any help would be awesome! Thanks a lot!
What i need is the camera position to be used in other Components. how do i get this?
pcace
August 8, 2023, 1:15pm
2
Hi there, got a little workaround for my problem wich definitely does not fix the issue, but makes it a littlebit better:
const prevPositionRef = useRef<Nullable<Vector3>>(null);
const [cameraPosition, setCameraPosition] = useState([0, 0]);
const timerRef = useRef<NodeJS.Timeout | null>(null); // timer als ref storen
if (camera && scene) {
const onBeforeRender = () => {
if (
!prevPositionRef.current ||
!prevPositionRef.current.equals(camera.position)
) {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
timerRef.current = setTimeout(() => {
setCameraPosition([camera.position.x, camera.position.y]);
}, 50); // if this gets lower or close to 1 i have the same result as before....
prevPositionRef.current = camera.position.clone();
}
};
camera.onAfterCheckInputsObservable.add(onBeforeRender);
}
useEffect(() => {
return () => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
};
}, []);
console.log(cameraPosition)
what would be the correct way to get data from babylon to react?!
This is kind of an annoying solution
cheers
11128
August 9, 2023, 9:10am
3
The first code shows that
react’s re-redner rules don’t expect the camera option to work, so if you want to get the value in the first form, try the following form
const camera = scene?.cameras[0]
const prevPositionRef = useRef<Nullable>(null);
const [cameraPosition, setCameraPosition] = useState<number >([0,0])
const [ justFlag, setJustFlag] = useState(false);
useEffect(() => {
if (camera) {
const onBeforeRender = () => {
if (!prevPositionRef.current || !prevPositionRef.current.equals(camera.position)) {
setJustFlag(true);
}
};
camera.onAfterCheckInputsObservable.add(onBeforeRender);
return () => {
camera.onAfterCheckInputsObservable.removeCallback(onBeforeRender);
};
}
}, [camera]);
useEffect(() => {
if(justFlag){
if(camera){
setCameraPosition([camera.position.x, camera.position.y]);
prevPositionRef.current = camera.position.clone();
}
setJustFlag(false);
}
return () => {
};
}, [justFlag]);
And if you only want that value in certain situations, you can just call the flags below and not use
onBeforeRender