简体   繁体   English

未捕获的类型错误:无法在 index.html:287 处读取动画 (index.html:266) 处未定义的属性“旋转”

[英]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.我的代码运行并显示它需要什么,但是当我尝试使用旋转或位置为 model 设置动画时出现此错误。 I have tried to maka a init function to run everything in it and that still did not work.我曾尝试使用 init function 来运行其中的所有内容,但仍然无法正常工作。 As soon as i stop animating the model in the animate function the error goes away but then it model is not spinning anymore.一旦我停止在动画 function 中为 model 设置动画,错误就会消失,但是 model 不再旋转。

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 .问题可能与planet有关。 You are attempting to access its rotation property inside the animation loop.您正试图在 animation 循环内访问其rotation属性。 This is fine!这可以!

BUT, you are assigning planet inside a loader callback.但是,您正在加载程序回调中分配planet This is also fine!这也不错!

BUT, loaders are asynchronous, and can take some time.但是,加载器是异步的,可能需要一些时间。 Your animation loop starts immediately.您的 animation 循环立即开始。

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.因此,当加载程序尝试下载并打开您的 GLTF 文件时,animation 循环尝试渲染场景。 Because planet isn't assigned yet, it holds the value undefined .因为planet尚未分配,所以它的值是undefined undefined obviously doesn't have a rotation property, and so you get an error. undefined显然没有rotation属性,所以你得到一个错误。

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.解决此问题的最简单方法是简单地将 animation 循环的那一部分包装在检查中以确保分配了变量。

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.或者,您可以将planet创建为THREE.Group ,然后将gltf.scene添加到加载程序回调中的适当组。

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.这也避免了错误,因为planet变量被初始化为THREE.Group ,它具有rotation属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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