我正在嘗試創建一個游戲,其中有一個影片角色,其中包含來自 Mixamo 的多個影片。我希望影片根據用戶在游戲中所做的事情而改變,例如Walking、Running或Idle。這是我加載FBX模型的方式(沒有影片):
loader.load('Assets/Animations/Main.fbx', function(object){
object.traverse(function (child){
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
child.frustumCulled = false;
}
});
object.rotation.x = Math.PI / 2
object.position.x = 11;
scene.add(object);
});
我還有以下檔案,它們是沒有皮膚的影片。
Idle.fbx
Walking.fbx
Running.fbx
我的目標是嘗試制作這樣或這樣的東西。這兩個鏈接的唯一問題是,在第一個鏈接中,他們使用了一個附加了多個影片的模型(我有一個帶有 3 個沒有皮膚的影片的普通模型),而在第二個鏈接中,代碼是使用TypeScript(我更喜歡JavaScript)。
我是 3D 建模的新手,所以我不知道如何將所有沒有皮膚的影片附加到主 fbx 模型。如何在 Blender 中將影片組合到一個模型中,或者有沒有辦法在 three.js 中做到這一點?
感謝您對此的任何幫助,謝謝!
編輯:
根據@GuyNachshon 的說法,這是我應該如何處理的嗎?
所以首先我加載沒有影片的模型(yourMesh),并創建一個AnimationMixer:
var mixer;
loader.load('Assets/Animations/Main.fbx', function(object){
object.traverse(function (child){
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
child.frustumCulled = false;
}
});
mixer = new THREE.AnimationMixer(object);
object.rotation.x = Math.PI / 2
object.position.x = 11;
scene.add(object);
});
然后,我必須加載 3 個沒有皮膚的影片檔案并將它們添加到animationsArray. (不確定我是否正確加載了影片......):
loader.load('Assets/Animations/Idle.fbx', function(object){
object.traverse(function (child){
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
child.frustumCulled = false;
}
});
object.rotation.x = Math.PI / 2
object.position.x = 11;
animationsArray.push(object);
scene.add(object);
});
loader.load('Assets/Animations/Walking.fbx', function(object){
object.traverse(function (child){
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
child.frustumCulled = false;
}
});
object.rotation.x = Math.PI / 2
object.position.x = 11;
animationsArray.push(object);
scene.add(object);
});
loader.load('Assets/Animations/Running.fbx', function(object){
object.traverse(function (child){
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
child.frustumCulled = false;
}
});
object.rotation.x = Math.PI / 2
object.position.x = 11;
animationsArray.push(object);
scene.add(object);
});
一切都完全加載后,我創建actions:
let actions = mixer.clipAction(animationsArray).play();
但是,在你說要做之后:
actions.play();
那條線要玩什么?它會播放第一個影片animationsArray嗎?
uj5u.com熱心網友回復:
您需要創建一個AnimationMixer.
所以假設你已經創建了一個場景,添加了一個網格等。現在你可以啟動一個影片混合器
let mixer = new THREE.AnimationMixer(yourMesh);
然后添加影片使用clipActions,
let actions = mixer.clipAction(animationsArray).play();
現在玩
actions.play();
但是要真正知道如何使用它,您應該閱讀檔案(附在上面:))
編輯 - 回應您的編輯
為了控制要播放的影片,您可以做幾件事,這是檔案中的一個示例:
const mixer = new THREE.AnimationMixer( mesh );
const clips = mesh.animations;
// Update the mixer on each frame
function update () {
mixer.update( deltaSeconds );
}
// Play a specific animation
const clip = THREE.AnimationClip.findByName( clips, 'dance' );
const action = mixer.clipAction( clip );
action.play();
// Play all animations
clips.forEach( function ( clip ) {
mixer.clipAction( clip ).play();
} );
現在,如果您在構建代碼時遇到問題,這里有一個關于如何將影片附加到 fbx 并控制它們的一般示例:
let mixer = THREE.AnimationMixer
let modelReady = false
const animationActions = THREE.AnimationAction
let activeAction = THREE.AnimationAction
let lastAction = THREE.AnimationAction
const fbxLoader = new FBXLoader()
在我們啟動了我們需要的一切之后,讓我們加載一切:
fbxLoader.load(
(object) => {
'path/to/your/model.fbx',
object.scale.set(0.01, 0.01, 0.01)
mixer = new THREE.AnimationMixer(object)
const animationAction = mixer.clipAction(animations[0])
animationActions.push(animationAction)
animationsFolder.add(animations, 'default')
activeAction = animationActions[0] // sets current animation
scene.add(object) // adds animated object to your scene
//add an animation from another file
fbxLoader.load(
'path/to/animation.fbx',
(object) => {
console.log('loaded animation')
const animationAction = mixer.clipAction(.animations[0])
animationActions.push(animationAction)
animationsFolder.add(animations, 'animationName')
//add an animation from another file
fbxLoader.load(
'path/to/other/animation.fbx',
(object) => {
console.log('loaded second animation')
const animationAction = mixer.clipAction(animations[0])
animationActions.push(animationAction)
animationsFolder.add(animations, 'animationName')
//add an animation from another file
fbxLoader.load(
'path/to/animation.fbx',
(object) => {
console.log('loaded third animation');
const animationAction = mixer.clipAction(animations[0])
animationActions.push(animationAction)
animationsFolder.add(animations, 'animationName')
modelReady = true
},
(xhr) => {
console.log(
(xhr.loaded / xhr.total) * 100 '% loaded'
)
},
(error) => {
console.log(error)
}
)
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 '% loaded')
},
(error) => {
console.log(error)
}
)
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 '% loaded')
},
(error) => {
console.log(error)
}
)
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 '% loaded')
},
(error) => {
console.log(error)
}
)
現在我們應該設定我們的影片和動作是什么:
const animations = {
function default() {
setAction(animationActions[0])
},
function firstAnimation() {
setAction(animationActions[1])
},
function sceondAnimation() {
setAction(animationActions[2])
},
function thirdAnimation() {
setAction(animationActions[3])
}
}
const setAction = {
if (toAction != activeAction) {
lastAction = activeAction
activeAction = toAction
//lastAction.stop()
lastAction.fadeOut(1)
activeAction.reset()
activeAction.fadeIn(1)
activeAction.play()
}
}
讓影片!
const clock = new THREE.Clock()
function animate() {
requestAnimationFrame(animate)
controls.update()
if (modelReady) {mixer.update(clock.getDelta())}
render()
}
function render() {
renderer.render(scene, camera)
}
animate()
把它們放在一起:
import * as THREE from 'three'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
let mixer = THREE.AnimationMixer
let modelReady = false
const animationActions = THREE.AnimationAction
let activeAction = THREE.AnimationAction
let lastAction = THREE.AnimationAction
const fbxLoader = new FBXLoader()
fbxLoader.load(
(object) => {
'path/to/your/model.fbx',
object.scale.set(0.01, 0.01, 0.01)
mixer = new THREE.AnimationMixer(object)
const animationAction = mixer.clipAction(animations[0])
animationActions.push(animationAction)
animationsFolder.add(animations, 'default')
activeAction = animationActions[0] // sets current animation
scene.add(object) // adds animated object to your scene
//add an animation from another file
fbxLoader.load(
'path/to/animation.fbx',
(object) => {
console.log('loaded animation')
const animationAction = mixer.clipAction(.animations[0])
animationActions.push(animationAction)
animationsFolder.add(animations, 'animationName')
//add an animation from another file
fbxLoader.load(
'path/to/other/animation.fbx',
(object) => {
console.log('loaded second animation')
const animationAction = mixer.clipAction(animations[0])
animationActions.push(animationAction)
animationsFolder.add(animations, 'animationName')
//add an animation from another file
fbxLoader.load(
'path/to/animation.fbx',
(object) => {
console.log('loaded third animation');
const animationAction = mixer.clipAction(animations[0])
animationActions.push(animationAction)
animationsFolder.add(animations, 'animationName')
modelReady = true
},
(xhr) => {
console.log(
(xhr.loaded / xhr.total) * 100 '% loaded'
)
},
(error) => {
console.log(error)
}
)
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 '% loaded')
},
(error) => {
console.log(error)
}
)
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 '% loaded')
},
(error) => {
console.log(error)
}
)
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 '% loaded')
},
(error) => {
console.log(error)
}
)
const animations = {
function default() {
setAction(animationActions[0])
},
function firstAnimation() {
setAction(animationActions[1])
},
function sceondAnimation() {
setAction(animationActions[2])
},
function thirdAnimation() {
setAction(animationActions[3])
}
}
const setAction = {
if (toAction != activeAction) {
lastAction = activeAction
activeAction = toAction
//lastAction.stop()
lastAction.fadeOut(1)
activeAction.reset()
activeAction.fadeIn(1)
activeAction.play()
}
}
const clock = new THREE.Clock()
function animate() {
requestAnimationFrame(animate)
controls.update()
if (modelReady) {mixer.update(clock.getDelta())}
render()
}
function render() {
renderer.render(scene, camera)
}
animate()
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/459086.html
標籤:javascript 动画片 三.js 搅拌机 米加莫
