I made a simple Earth sphere rotating around 0 axis. Then I have added a child (the moon) but I can't figure if it is possible to also modify its position inside the useFrame hook of the Earth.
const Earth = (props) => {
const ref = useRef()
const texture = useLoader(THREE.TextureLoader, "/03earth.jpg")
const coef = 0.1
const delta = 6
useFrame(state => {
ref.current.rotation.y += 0.01
ref.current.position.x = Math.cos(state.clock.elapsedTime * coef) * delta
ref.current.position.z = Math.sin(state.clock.elapsedTime * coef) * delta
})
return (
<mesh ref={ref} {...props} castShadow receiveShadow>
<sphereGeometry />
<meshPhysicalMaterial map={texture} />
<Moon/> )
you can access sub components by specifying their index in children:
import "./styles.css";
import React, { useRef } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
import * as THREE from "three";
export default function App() {
return (
<div className="App" style={{ width: "100vw", height: "100vh" }}>
<Canvas>
<OrbitControls />
<Earth />
</Canvas>
</div>
);
}
const Earth: React.FC = () => {
const ref = useRef(null);
useFrame((state) => {
ref.current.rotation.y = state.clock.getElapsedTime();
// Here
ref.current.children[0].position.y = Math.sin(state.clock.getElapsedTime());
});
return (
<mesh ref={ref}>
<sphereGeometry args={[1, 32, 32]} />
<meshNormalMaterial />
<mesh position={[1, 1, 1]}>
<sphereGeometry args={[0.2, 32, 32]} />
<meshNormalMaterial />
</mesh>
</mesh>
);
};
sandbox https://codesandbox.io/s/inspiring-rgb-ry2f1h?file=/src/App.tsx