アバターをアニメーションで動かしてみよう

今回は「ワールドに入室したプレイヤーのアバターのポーズを変えさせる」機能を使ったアイテムの作成方法を紹介します。
この機能を使って、アバターにアニメーションを適用してみましょう。

新しい空のGameObjectにScriptable Itemコンポーネントを追加します。
子オブジェクトにモデルやコライダーも配置しておきましょう。

アイテムに「Humanoid Animation List」コンポーネントを追加します。
Humanoid Animationsの項目をひとつ追加し、スクリプトで参照するためのIDと、Humanoid用のAnimationファイルを設定します。今回はIDを「Animation1」とし、AnimationにはMixamoからダウンロードしたものを設定しています(MixamoからダウンロードしたAnimationの使い方はこちら)。

Scriptable Itemに以下のスクリプトを設定します。

// アニメーションクリップを取得
const animation = $.humanoidAnimation("Animation1");


// アニメーションクリップの長さを取得
const animationLength = animation.getLength();


// アニメーション適用間隔を設定(プレイヤーへの操作の頻度制限)
const interval = 0.1;


// クリックしたときの処理
$.onInteract(player => {
    // 既にアニメーション再生中のプレイヤーがいる場合はリセット
    if ($.state.player) {
        $.state.player.setHumanoidPose(null);
    }


    // アニメーションの時間をリセット
    $.state.animationTime = 0;


    // クリックした人をアニメーションの対象にする
    $.state.player = player;
});


// 毎フレーム実行される処理
$.onUpdate(deltaTime => {
    // 初期化
    if (!$.state.initialized) {
        $.state.initialized = true;
        $.state.player = null;
        $.state.animationTime = 0;
        $.state.waitingTime = 0;
    }


    // 対象のプレイヤーを取得。対象がない、または退室済みなどの場合は終了
    let player = $.state.player;
    if (!player || !player.exists()) return;    


    // アニメーションの再生時間を更新
    let animationTime = $.state.animationTime + deltaTime;


    // 再生時間がアニメーションの長さを超えていたらリセットして終了
    if (animationTime > animationLength) {
        if (player) {
            player.setHumanoidPose(null);
        }
       
        $.state.player = null;
        return;
    }


    // 前回ポーズを設定してからの時間を更新
    let waitingTime = $.state.waitingTime + deltaTime;


    // 前回ポーズを設定してから一定時間が経過していた場合にポーズを更新
    if (waitingTime >= interval) {
        // アニメーションクリップから現在の再生時間でのポーズを取得
        let pose = animation.getSample(animationTime);


        // プレイヤーにポーズを適用
        player.setHumanoidPose(pose);


        // 経過時間をリセット
        waitingTime = 0;
    }


    $.state.animationTime = animationTime;
    $.state.waitingTime = waitingTime;
});
const animation = $.humanoidAnimation("Animation1");

$.humanoidAnimation()メソッドで、Humanoid Animation Listコンポーネントに設定したアニメーションを取得できます。引数にはHumanoid Animation Listで設定したIDを指定します。

let pose = animation.getSample(animationTime);

HumanoidAnimation.getSample()メソッドで、アニメーションの特定の時間におけるポーズを取得することができます。

player.setHumanoidPose(pose);

PlayerHandle.setHumanoidPose()で、対象のアバターのポーズを指定したものに変更することができます。
また、引数にnullを渡すことでポーズをリセットし、通常のモーションに戻すことができます。

let waitingTime = $.state.waitingTime + deltaTime;
if (waitingTime >= interval) {
(略)
    waitingTime = 0;
}

PlayerHandle.setHumanoidPose()などのPlayerHandleに対する操作には頻度制限があります。
毎フレーム呼び出すと制限を超えてしまうため、一定時間が経過するごとに呼び出すようにしています。

記事をシェアしてワールド制作を盛り上げよう!

Cluster Creators Guide|バーチャル空間での創作を学ぶならをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む