0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

店舗接客などに使える仮想のキャラクターが扱えるアプリ開発をしました。そちらの説明はこちらになります。
https://qiita.com/NestVisual/items/fe4dd168178e27156682

環境:
Windows 10
Unity 2018.4.1
RealSense D435i

キャラのアニメーション:

利用者の骨格が検出されなかったり、カメラと利用者の距離が遠すぎたり近すぎたりなど、様々な理由で骨格トラッキングが反映されないときに、モデルはその場で止まってしまいます。これは人形のように見えます。そして、モデルが不自然な状態にある場合は特に悪い。

これを変更するには、まずモデルの四肢の回転を元の状態にリセットしました。Quaternion.Lerp() メソッドを使用すると、スムーズに動きましたが、人間らしくありませんでした。人間は完全に静止していることはほとんどないので、少しだけ揺れる待機状態のループ再生アニメーションが必要だと思いました。

最大の問題は、モデルのトラッキング反映ポーズから、アニメーションの開始ポーズまでを自然に移動させることでした。単純にアニメーションを再生するだけでは、急に変化してしまいます。

現行のプロジェクトでは、アニメーションはすぐに再生されます。そして、再生前の四肢の回転を保存します。これからLateUpdate()でまたLerp()を使用して、関節の回転を設定します。これを行うには、Quaternion.Slerp()を使用します。これは2つの回転と、それらの影響を決定するブレンド比を受け取ります。この比率は、アニメーションの再生が始まったからの経過時間を基準にしています。保存した回転の影響が徐々に少なくなっていきます。

sample1.cs
private void LateUpdate()
{ BlendToMecanim(); }

/// <summary> トラッキング反映からスムーズにMecanimにブレンド移行。Mecanimによってオーバーライドされないように、LateUpdateで呼ぶ </summary>
private void BlendToMecanim()
{
    _animator.SetBool("Idle", false);
    if (STATE != ControlState.BLEND_TO_ANIM)    return;

    // Mecanimに移行したら過ごした時間
    float timePassed = Time.time - reflectTrackingEndTime;                             
    // どれぐらい最後のトラッキングポーズを表す
    float trackingBlendRatio = 1.0f - timePassed / trackingToMecanimBlendTime; 
    // 0から1まで
    trackingBlendRatio = Mathf.Clamp01(trackingBlendRatio);

    // 関節をtrackingBlendRatioぐらいで最後のトラッキング回転にオフセットする
    foreach (KeyValuePair<nuitrack.JointType, Quaternion> rotation in _jointRotationsBeforeMecanim)
    {
        ModelJoint modelJoint = _jointsRigged[rotation.Key];
        modelJoint.bone.rotation = Quaternion.Slerp(modelJoint.bone.rotation, rotation.Value, trackingBlendRatio);
    }

    if (trackingBlendRatio == 0)    STATE = ControlState.ANIMATED;
}

上記プログラムでは、カメラのトラッキングデータを、キャラのアニメーションに反映させます。同じシステムを他のアニメーションにも使用ができます。例えば、複雑な手のジェスチャーのようなトラッキングが難しいものです。BlendToMechAnimメソッドがUpdate()ではなくLateUpdate()で呼ばれるのは、アニメーションの次のフレームが更新されたの後に回転を設定するためです。Updateを使用した場合、アニメーションはブレンドされた回転を上書きしてしまいます。同じスクリプトには 「ControlState」という列挙もあります。これはキャラクターが骨格トラッキング、Unityでのアニメーション(mecanim)、mecanimに向かってブレンドされているときの状態を持っています。

次回はフェイストラッキングで顔を操るに関して投稿します。それではまた

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?