Reputation: 1
I am working on a DOTA2 website and try to add heros' 3D model in the web. I extracted a hero's model, but it includes many gltf files and textures. One of files is the hero's body and the rest are asscesories, such as hat, weapon, clouth.
I try to play the animation of the model, but only the body part gltf file includes animations, the rest part doesn't have any animation. Thus, when I play the animation, only the hero's body is acting, the rest part is fixed.
Here is my code:
import * as THREE from 'three'
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { useRef, useEffect } from 'react'
import './App.css'
import { AmbientLight } from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
const modelList = [
'warlock.gltf',
'warlock_bag.gltf',
'warlock_bracers.gltf',
'warlock_cape.gltf',
'warlock_lantern.gltf',
'warlock_robe.gltf',
'warlock_shoulder.gltf',
'warlock_staff.gltf'];
function App() {
const mount = useRef(null);
const mixer = useRef(null);
useEffect(() => {
const loader = new GLTFLoader();
const scene = new THREE.Scene();
const clock = new THREE.Clock();
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
mount.current.appendChild(renderer.domElement);
const ambientLight = new AmbientLight(0xffffff, 1);
scene.add(ambientLight);
const grayColor = new THREE.Color(0.5, 0.5, 0.5);
scene.background = grayColor;
camera.position.z = 5;
camera.position.y = 5;
camera.position.x = 5;
camera.lookAt(0, 0, 0);
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
var character = null;
loader.load(`model/warlock.gltf`, (gltf) => {
character = gltf.scene;
scene.add(character);
mixer.current = new THREE.AnimationMixer(gltf.scene);
const animation = gltf.animations[1];
if (animation) {
const action = mixer.current.clipAction(animation);
action.play();
}
LoadOtherPart();
console.log(gltf);
animate();
});
function LoadOtherPart() {
modelList.forEach((model) => {
loader.load(`model/${model}`, (gltf) => {
if(model !== 'warlock.gltf'){
character.add(gltf.scene);
}
});
})
}
function animate() {
requestAnimationFrame(animate);
if(mixer.current){
const delta = clock.getDelta();
mixer.current.update(delta);
}
renderer.render(scene, camera);
controls.update();
}
return () => {
mount.current.removeChild(renderer.domElement);
};
}, []);
return (
<div ref={mount}>
</div>
)
}
export default App;
I thought the rest part should be the children of the body part, and the gltf file may include the relative position data. I try it, but it still doesn't work. Is it possible only use the threejs to achieve that accessories animate with the body properly? How can I solve the problem?
Thank you so much!
Upvotes: 0
Views: 41