i make a hybrid desktop/vr fps shooter . i have an eryops some kind of crocodile . it is animated with a morph to make it crawl . when it gets shot it makes a deathroll with a quaternion and a jump upwards and a fall and a euler rotation while still wiggling its legs by the crawling morph. . this works well in desktop . but in vr . he only jumps in the air , frozen and dissappears .this is the animation code.It sits in a killzombie function that sits in an function updatebullets that sits in the animate function
if (type === ‘eryops’) {
const model = zombie.children.find(child => child.isObject3D);
if (!model) return;
model.position.y += 0.8; // Lift model to avoid floor clipping
const duration = 0.7;
const start = performance.now();
const initialY = zombie.position.y;
const fallY = initialY - 0.3;
const startQuat = model.quaternion.clone();
const endQuat = startQuat.clone().multiply(
new THREE.Quaternion().setFromEuler(new THREE.Euler(Math.PI, 0, 0)) // Side roll on X
);
function animateRoll(now) {
const elapsed = (now - start) / 1000;
//const t = Math.min(elapsed / duration, 1);
const raw = Math.min(elapsed / duration, 1);
//const t = raw * raw; // ease-out
const t = 1 - Math.pow(1 - raw, 3); // ease-out cubic
// Combined roll and spin using a dynamic quaternion
const flipDir = Math.random() < 0.5 ? 1 : -1;
const spinDir = Math.random() < 0.5 ? 1 : -1;
const roll = flipDir * Math.PI * t;
const spin = spinDir * Math.PI * 1.5 * (1 - t);
const comboQuat = new THREE.Quaternion().setFromEuler(
new THREE.Euler(roll, 0,spin) // rotate X and Y together
);
// Drop the zombie slightly
zombie.position.y = initialY * (1 - t) + fallY * t;
model.quaternion.copy(comboQuat);
zombie.updateMatrixWorld(true);
if (t < 1) {
requestAnimationFrame(animateRoll);
}
}
//if (type === ‘eryops’) {
const action = zombie.userData.actions?.crawl;
if (action && !action.isRunning()) {
action.reset();
action.setLoop(THREE.LoopRepeat);
action.play();
}
//}
requestAnimationFrame(animateRoll);
}