How can I make a 3D Object follow a predetermined path & rotate? (as if it's on a train track)

In my imported 3D model, I have a streetcar that should follow a curved track
(red line is the track).

Video (imgur link)

The way i’ve written my code is as follows

  • Found the Object name (i.e Object_97) for each part
  • moved each object part’s x with the function += Math.sin(time) * 0.5;

Question 1)
The image showcases the track’s curve that the streetcar should follow. Right now, I only got the streetcar to go back and forth. How can I get it to follow the track.

Question 2)
Another issue is rotation. The streetcar needs to turn as it’s following the track. How can I do that?

My code:

useEffect(() => {
    // Boiletplate Code Omitted 
    // ...
    let loadedModel;
    let streetcar; // colored, 'Object_97'
    let streetcar_wf; // wireframe 'Object_95'
    let streetcar_mirror; // mirrors, Object_91'
    let streetcar_wheel1; // Object_101
    let streetcar_wheel2; // Object_105
    let streetcar_misc; // misc stuff Object_93
    const clock = new THREE.Clock();
    const glftLoader = new GLTFLoader();
    glftLoader.load('./assets/littlest_tokyo/scene.gltf', (gltfScene) => {
      loadedModel = gltfScene;
      console.log(gltfScene.scene); 
      gltfScene.scene.position.z = 13;
      
      // animate the streetcar by selecting all objs.
      streetcar = gltfScene.scene.getObjectByName('Object_97'); //colored part
      streetcar_wf = gltfScene.scene.getObjectByName('Object_95'); //wireframe
      streetcar_mirror = gltfScene.scene.getObjectByName('Object_91'); //mirrors
      streetcar_wheel1 = gltfScene.scene.getObjectByName('Object_101'); //wheel 1
      streetcar_wheel2 = gltfScene.scene.getObjectByName('Object_105'); //wheel 2
      streetcar_misc = gltfScene.scene.getObjectByName('Object_93'); //misc stuff
      

      if (streetcar && streetcar_wf && streetcar_mirror && streetcar_wheel2 && streetcar_wheel1 && streetcar_misc) {
        streetcar.position.z = 0; // Initial position
        streetcar_wf.position.z = 0; // Initial position
        streetcar_mirror.position.z = 0; // Initial position
        streetcar_wheel1.position.z = 0; // Initial position
        streetcar_wheel2.position.z = 0; // Initial position
        streetcar_misc.position.z = 0

      }
      test.scene.add(gltfScene.scene);
    });

const animateStreetcar = () => {
      if (streetcar) {
        const time = clock.getElapsedTime();
        streetcar.position.x += Math.sin(time) * 0.5; // Moves back and forth along the z-axis
        streetcar_wf.position.x += Math.sin(time) * 0.5;
        streetcar_mirror.position.x += Math.sin(time) * 0.5;
        streetcar_wheel1.position.x += Math.sin(time) * 0.5;
        streetcar_wheel2.position.x += Math.sin(time) * 0.5;
        streetcar_misc.position.x += Math.sin(time) * 0.5;
        console.log('peepeeman')
      }
    };

It should look like this sketchfab 3d model (sketchfab link)

What I tried
I tried finding the Object_number of the track and have the train float above it, but the Object number of the track is the same as a lot of bushes and stuff.

I’m thinking of finding a function that overlaps/corresponds with the track, and having the streetcar move on that function.

I’d love some help in finding that function and rotating the streetcar as if it were following that track :–P

Thank you!

You could figure out the path vertices and use Tween js to move the object.

Here’s a related repo: