Reputation: 33
I've created this example from a GLTF file of Dragonball animation on scroll, but i couldn't achieve my goal which is the user should feel like he is the one riding the car ( 1st person perspective ), How can i do that?
Also i have a question, when the model first appear, it shows the world as a sphere the the camera change its focus to the car, How can focus the camera on 1st person perspective from the beginning?
Here is the example i'm working on:
https://codesandbox.io/s/dbz-snake-path-ecz8ul
import * as THREE from "three";
import { Suspense, useEffect } from "react";
import { Canvas, useFrame, useLoader } from "@react-three/fiber";
import {
ScrollControls,
useScroll,
useAnimations,
Stage
} from "@react-three/drei";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
const Model = ({ ...props }) => {
// This hook gives you offets, ranges and other useful things
const scroll = useScroll();
const { scene, animations } = useLoader(GLTFLoader, "/model/scene.gltf");
const { actions } = useAnimations(animations, scene);
let car = scene.getObjectByName("car");
useEffect(() => {
actions["Take 001"].play().paused = true;
}, [actions]);
useFrame((state, delta) => {
// Animate on scroll
const action = actions["Take 001"];
const offset = scroll.offset;
action.time = THREE.MathUtils.damp(
action.time,
action.getClip().duration * offset,
100,
delta
);
// Camera to follow car element
let position = new THREE.Vector3(0, 0, 0);
position.setFromMatrixPosition(car.matrixWorld);
let wDir = new THREE.Vector3(0, 0, 1);
wDir.normalize();
let cameraPosition = position
.clone()
.add(wDir.clone().multiplyScalar(1).add(new THREE.Vector3(0, 0.3, 0)));
wDir.add(new THREE.Vector3(0, 0.2, 0));
state.camera.position.copy(cameraPosition);
state.camera.lookAt(position);
});
return <primitive object={scene} {...props} />;
};
const App = () => {
return (
<>
<Suspense fallback={null}>
<Canvas>
<Stage environment={null}>
<ScrollControls pages={10}>
<Model scale={1} />
</ScrollControls>
</Stage>
</Canvas>
</Suspense>
</>
);
};
export default App;
Upvotes: 1
Views: 633
Reputation: 28472
You should simply add the camera
as a child Object of the car
. That way when you move the car forward, the camera will immediately follow.
// Add camera as child of car
car.add(camera);
// Now the camera will move and rotate with the car
car.position.set(x, y, z);
car.rotation.y = angle;
You might need to adjust the camera's position at first so it's placed behind the character, or maybe above, that's up to you.
Upvotes: 1