简体   繁体   中英

Uncaught TypeError: Cannot read property 'rotation' of undefined at animate (index.html:266) at index.html:287

My Code Runs and show what it needs, however this error apears when i try to animate a model with rotation or posotion. I have tried to maka a init function to run everything in it and that still did not work. As soon as i stop animating the model in the animate function the error goes away but then it model is not spinning anymore.

let model;
let mixer;
let model2;
let mixer2;
let mixer3, mixer4, mixer5, mixer6;
let planet;

//BUTTON
//let startButton = document.getElementById("startButton");
//if(startButton){
//startButton.addEventListener("click");
//s }

//SOUND INPUT TONE.JS

const player = new Tone.Player("sound/whale.wav").toDestination();
// play as soon as the buffer is loaded
player.loop = true;
player.volume.value = -15;

player.autostart = true;

const player2 = new Tone.Player("sound/space.wav").toDestination();
// play as soon as the buffer is loaded
player2.loop = true;
player2.autostart = true;

//sfunction init (){
const MODEL_PATH = "model/stacy.gltf";

clock = new THREE.Clock();
//CREATE SCENE AND CAMERA
const scene = new THREE.Scene();
const backgroundColor = 0x000000;
scene.background = new THREE.Color(backgroundColor);
const camera = new THREE.PerspectiveCamera(
  70,
  window.innerWidth / window.innerHeight,
  0.01,
  100
);

camera.position.y = 40;
//CREATE RENDERER
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

camera.position.z = 50;
camera.position.y = 40;

var loader = new THREE.GLTFLoader().setPath("model/car/");
loader.load("scene.gltf", function (gltf) {
  mixer = new THREE.AnimationMixer(gltf.scene);
  var action = mixer.clipAction(gltf.animations[0]);
  action.play();

  scene.add(gltf.scene);
  gltf.scene.position.x += 0.2;
  gltf.scene.rotation.y = -1.3;
  gltf.scene.scale.set(2, 2, 2);
  gltf.scene.position.set(15, -15, 40);
  model2 = gltf.scene;
});

var loader = new THREE.GLTFLoader().setPath("model/statue/");
loader.load("scene.gltf", function (gltf) {
  mixer3 = new THREE.AnimationMixer(gltf.scene);
  var action = mixer3.clipAction(gltf.animations[0]);
  action.play();

  scene.add(gltf.scene);
  //gltf.scene.rotation.y =-1.3;
  gltf.scene.scale.set(6, 6, 6);
  gltf.scene.position.set(0, -70, -45);
});

var loader = new THREE.GLTFLoader().setPath("model/robot/");
loader.load("scene.gltf", function (gltf) {
  mixer5 = new THREE.AnimationMixer(gltf.scene);
  var action = mixer5.clipAction(gltf.animations[0]);
  action.play();

  scene.add(gltf.scene);
  gltf.scene.rotation.x = -1.3;
  gltf.scene.rotation.z = -1.3;
  gltf.scene.scale.set(4, 4, 4);
  gltf.scene.position.set(-5, -55, 25);
});

var loader = new THREE.GLTFLoader().setPath("model/blackhole/");
loader.load("scene.gltf", function (gltf) {
  mixer4 = new THREE.AnimationMixer(gltf.scene);
  var action = mixer4.clipAction(gltf.animations[0]);
  action.play();

  scene.add(gltf.scene);

  gltf.scene.rotation.x = -1.7;
  gltf.scene.scale.set(0.5, 0.5, 0.5);
  gltf.scene.position.set(0, -70, -30);
});

var loader = new THREE.GLTFLoader().setPath("model/galaxy/");
loader.load("scene.gltf", function (gltf) {
  scene.add(gltf.scene);

  gltf.scene.scale.set(0.5, 0.5, 0.5);
  gltf.scene.position.set(10, -100, 30);
  planet = gltf.scene;
});

//STARS
let starGeo, stars;

starGeo = new THREE.Geometry();
for (let i = 0; i < 6000; i++) {
  let star = new THREE.Vector3(
    Math.random() * 600 - 300,
    Math.random() * 600 - 300,
    Math.random() * 600 - 300
  );
  starGeo.vertices.push(star);
}
let sprite = new THREE.TextureLoader().load("img/star.png");
let starMaterial = new THREE.PointsMaterial({
  color: 0xffffff,
  size: 0.7,
  map: sprite,
});
stars = new THREE.Points(starGeo, starMaterial);
scene.add(stars);

//LIGHTS

const pointLight = new THREE.PointLight(0xff3f0f, 15, 100);
pointLight.position.set(0, -100, 0);
scene.add(pointLight);

const sphereSize = 3;
const pointLightHelper = new THREE.PointLightHelper(pointLight, sphereSize);
scene.add(pointLightHelper);

const pointLight2 = new THREE.PointLight(0xff3f0f, 15, 100);
pointLight2.position.set(0, -50, 0);
scene.add(pointLight2);

const sphereSize2 = 3;
const pointLightHelper2 = new THREE.PointLightHelper(pointLight2, sphereSize2);
scene.add(pointLightHelper2);

//onWINDOWRESIZE FUNCTION
function onWindowResize() {
  //resize & align
  sceneHeight = window.innerHeight;
  sceneWidth = window.innerWidth;
  renderer.setSize(sceneWidth, sceneHeight);
  camera.aspect = sceneWidth / sceneHeight;
  camera.updateProjectionMatrix();
}

// ANIMATE FUNCTION

function animate() {
  requestAnimationFrame(animate);

  var t = scrollY / (5000 - innerHeight);
  // t is 0 to 1
  camera.position.y = 0.01 - (800 * t) / 80;

  stars.rotation.y += 0.0005;

  planet.rotation.y += 0.005;

  var delta = clock.getDelta();

  if (mixer) mixer.update(delta / 2);
  if (mixer2) mixer2.update(delta);
  if (mixer3) mixer3.update(delta / 10);
  if (mixer4) mixer4.update(delta / 10);
  if (mixer5) mixer5.update(delta / 4);
  if (mixer6) mixer6.update(delta / 0.1);

  renderer.render(scene, camera);
}

animate();

The problem is likely with planet . You are attempting to access its rotation property inside the animation loop. This is fine!

BUT, you are assigning planet inside a loader callback. This is also fine!

BUT, loaders are asynchronous, and can take some time. Your animation loop starts immediately.

So what's happening is while the loaders are trying to download and open your GLTF files, the animation loop tries to render the scene. Because planet isn't assigned yet, it holds the value undefined . undefined obviously doesn't have a rotation property, and so you get an error.

The easiest way to get around this is to simply wrap that part of your animation loop in a check to ensure the variable is assigned.

if( planet ){
  planet.rotation.y += 0.005;
}

This will ensure you aren't trying to update a property of a value that doesn't exist.

Alternately, you could create planet as THREE.Group , then add the gltf.scene to the appropriate group in the loader's callback.

let planet = new THREE.Group();
scene.add(planet);

loader.load(path, function( gltf ){
  //...
  planet.add( gltf.scene );
  //...
});

This also avoids the error because the planet variable is initialized as a THREE.Group , which has a rotation property.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM