Since your code contains quite a lot of things that are unimportant for the thing under consideration, I shortened it to make it easier to understand.
I took a cuboid instead of the cylinder to see the orientation.
To this add a model. As you can see, the bee flies quite peculiar.
Something is missing there. But what?
Link MoveAlongCurve
<!DOCTYPE html>
<!-- https://discourse.threejs.org/t/struggling-with-paths/26486/7 -->
<head>
<title> MoveAlongCurve </title>
<meta charset="utf-8" />
</head>
<body></body>
<script type="module">
import * as THREE from "../jsm/three.module.128.js";
import { OrbitControls } from "../jsm/OrbitControls.128.js";
import { GLTFLoader } from "../jsm/GLTFLoader.128.js";
const renderer = new THREE.WebGLRenderer( {antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setPixelRatio( devicePixelRatio );
document.body.appendChild(renderer.domElement);
const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( -2.5, 2, 0 );
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x11aa11);
const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.6 );
directionalLight.position.set( 0, 20, 15 );
scene.add( directionalLight );
new OrbitControls( camera, renderer.domElement );
let newPosition, tangent, radians;
let fraction = 0;
const up = new THREE.Vector3( 0, 1, 0 );
let axis = new THREE.Vector3( );
const pointsPath = new THREE.CurvePath();
const bezierLine = new THREE.CubicBezierCurve3(
new THREE.Vector3( 1, 0, -1 ),
new THREE.Vector3( 1, 0, 1 ),
new THREE.Vector3( -1, 0, 1 ),
new THREE.Vector3( -1, 0, -1 ),
);
pointsPath.add( bezierLine );
const material = new THREE.MeshNormalMaterial( { wireframe: true } );
const box = new THREE.BoxGeometry( 0.05, 0.4, 0.2 );
const char = new THREE.Mesh( box, material );
scene.add( char );
const modelBee = new THREE.Object3D( );
const loader = new GLTFLoader( ).load( 'Kelli Ray_Bee/toi uu.gltf', processBee );
modelBee.scale.set( 0.005, 0.005, 0.005 ); // because gltf.scene is very big
modelBee.rotation.y = Math.PI / 2;
modelBee.rotation.z = -Math.PI / 2;
char.add( modelBee );
const material2 = new THREE.LineBasicMaterial({ color: 0x9132a8});
const points = pointsPath.curves.reduce( ( p, d ) => [...p, ...d.getPoints( 20 )], [] );
const geometry2 = new THREE.BufferGeometry( ).setFromPoints( points );
const liner = new THREE.Line( geometry2, material2 );
scene.add(liner);
animate();
function animate() {
fraction += 0.0004;
if ( fraction > 1 ) fraction = 0;
newPosition = pointsPath.getPoint( fraction );
tangent = pointsPath.getTangent( fraction );
char.position.copy( newPosition );
axis.crossVectors( up, tangent ).normalize( );
radians = Math.acos( up.dot( tangent ) );
char.quaternion.setFromAxisAngle( axis, radians );
requestAnimationFrame( animate );
renderer.render( scene, camera );
};
function processBee( gltf ) { // Kelli Ray (CC-BY) Poly by Googl
const box = new THREE.Box3( ).setFromObject( gltf.scene );
const c = box.getCenter( new THREE.Vector3( ) );
const size = box.getSize( new THREE.Vector3( ) );
gltf.scene.position.set( -c.x, size.y / 2 - c.y, -c.z ); // center the gltf scene
modelBee.add( gltf.scene );
}
</script>
</html>