このセクションでは、VRMモデルの関節を操作してアニメーションを作成する方法を学びます。
VRMモデルには、人間の骨格に対応したボーンがあります。
これを利用することで、アバターの動きを制御することができます。
ボーンの一覧は次の通りです。
よく使うものをハイライトしています。
ここでは、作成したVRMモデルを sample.vrm
という名前で保存したとします。
サンプルのモデルファイルをこちらからダウンロードしても構いません。
モデルファイルは、プログラムのファイルと同じ場所に配置してください。
VRMモデルのボーンを取得するには、モデル.bone(ボーン名)
を使います。
得られたボーンは、rotation
で回転操作を行うことができます。
例えば、右上腕を回転させる場合、次のようにします。
model.bone("rightUpperArm").rotation.z = 回転角
モデルのボーンを操作した場合、最後に model.update(delta)
をしないと変更が反映されません。
今の場合、次のようにするとVRMモデルの右腕全体を動かすことができます。
const { camera, create, animate, controls, load, helper } = init()
controls.connect()
camera.position.set(0, 1.3, -1.5)
controls.target.set(0, 1, 0)
helper.grid({ size: 10 })
helper.axes()
create.ambientLight({ intensity: 0.2 })
create.directionalLight({
intensity: 2,
position: [-10, 10, -10]
})
create.plane({
size: 10,
rotation: [-Math.PI / 2, 0, 0],
option: {
color: 0xaaaaaa,
}
})
let model
load.vrm("./sample.vrm").then((m) => (model = m))
animate(({ time, delta }) => {
if (model) {
model.bone("rightUpperArm").rotation.z = Math.sin(time) * Math.PI * 0.25
model.update(delta)
}
})
決まった回転角で固定するなら、読み込み時に指定することもできます。
下の例は、右上腕、右ひじ、首、頭をアニメーションさせつつ、左上腕は固定の角度で固定する例です。
const { camera, create, animate, controls, load, helper } = init()
controls.connect()
camera.position.set(0, 1.3, -1.5)
controls.target.set(0, 1, 0)
helper.grid({ size: 10 })
helper.axes()
create.ambientLight({ intensity: 0.2 })
create.directionalLight({
intensity: 2,
position: [-10, 10, -10]
})
create.plane({
size: 10,
rotation: [-Math.PI / 2, 0, 0],
option: {
color: 0xaaaaaa,
}
})
let model
load.vrm("./sample.vrm").then((m) => {
model = m
model.bone("leftUpperArm").rotation.z = Math.PI * 0.4
})
animate(({ time, delta }) => {
if (model) {
model.bone("rightUpperArm").rotation.z = Math.sin(time) * Math.PI * 0.25
model.bone("neck").rotation.x = Math.sin(time) * Math.PI * 0.25
model.bone("head").rotation.y = Math.cos(time * 1.6) * Math.PI * 0.25
model.bone("rightLowerArm").rotation.y = -Math.sin(time * 1.4) * Math.PI * 0.25 + Math.PI * 0.25
model.update(delta)
}
})
VRMモデルのボーンを操作するときに大切なことは、 「自分の体でその動きをするとき、なにを動かしているのか」 を意識することです。
例えば上を向く場合は「頭が回転」します。
一方で、右を向く場合は「首が回転」することで、 結果的に頭も回転しているように見えます(が、実際は首と頭の間の関係は変わっていないので頭は回転していません)。
モデルの表情を変えるには、
model.expressionManager.setValue("表情名", 強さ)
とします。
強さは0から1の間で指定します。
ボーンと同様に、model.update(delta)
をしないと変更が反映されません。
表情名は次のものがあります。
モデルによっては、該当する表情がない場合があります。
例えば、次のように記述すると、 嬉しい表情と通常の表情を繰り返します。
const { camera, create, animate, controls, load, helper } = init()
controls.connect()
camera.position.set(0, 1.3, -1.5)
controls.target.set(0, 1, 0)
helper.grid({ size: 10 })
helper.axes()
create.ambientLight({ intensity: 0.2 })
create.directionalLight({
intensity: 2,
position: [-10, 10, -10]
})
create.plane({
size: 10,
rotation: [-Math.PI / 2, 0, 0],
option: {
color: 0xaaaaaa,
}
})
let model
load.vrm("./sample.vrm").then((m) => (model = m))
animate(({ time, delta }) => {
if (model) {
model.expressionManager.setValue("happy", Math.sin(time)*0.5 + 0.5)
model.update(delta)
}
})