Unity ステッピング ピット ノート - クォータニオン ローテーション (例としてボーンを使用)

Unity ステッピング ピット ノート - クォータニオン ローテーション (例としてボーンを使用)


次の内容は、学習の参照、学習ノートのみを目的としています。エラー修正のためにコメント領域にメッセージを残してください。

序文

ローテーションは常に頭の痛い問題でした。左手または右手、外回転または内回転、ワールド座標またはローカル座標。ローテーションの形でどちらを選ぶか、気をつけないと失敗します。ボーンと同様に、親関節に対する相対データもあり、このデータの動作が変化すると、関節の座標系も変化する可能性があります。したがって、最も単純なのはワールド座標であり、回転したオブジェクトの配置を厳密に要求する必要があります。
回転形式には多くの種類があり、ここで選択された回転形式はオイラー角と四元数であり、オイラー角は最も簡単に得られるデータです。

シーン設定

最初にアバターの位置を確認します
ここに画像の説明を挿入
ここで選択した関節はLeftUpperArmデモンストレーション用であり、ワールド座標とローカル座標の違いを見つけることができます。

ローカル回転テスト

これがローカル回転テストです。ローカル z を中心に回転します。

public class test : MonoBehaviour
{
    
    
    Animator animator;
    float deltaz = 0f;
    Vector3 upperArm = new Vector3(0f, 0f, 0f);
    Quaternion prevQ;

    void Start()
    {
    
    
       
        // 获取动画控件
        animator = this.GetComponent<Animator>();
        // 获取原始旋转
        prevQ = animator.GetBoneTransform(HumanBodyBones.LeftUpperArm).rotation;
        Quaternion currentQ = Quaternion.Euler(upperArm.x, upperArm.y, upperArm.z);
        animator.GetBoneTransform(HumanBodyBones.LeftUpperArm).rotation = currentQ * prevQ;
    }

    // Update is called once per frame
    void Update()
    {
    
    
        deltaz += 1f;
        upperArm.z = deltaz;
        Quaternion currentQ = Quaternion.Euler(upperArm.x, upperArm.y, upperArm.z);
        animator.GetBoneTransform(HumanBodyBones.LeftUpperArm).rotation =  prevQ * currentQ;
    }
}

ここに画像の説明を挿入

  • ローカル座標系が変わると、結果も変わります。下の図を参照してください。

ここに画像の説明を挿入

世界回転テスト

これは世界の回転テストです。コードはわずかに異なります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class test : MonoBehaviour
{
    
    
    Animator animator;
    float deltaz = 0f;
    Vector3 upperArm = new Vector3(0f, 0f, 0f);
    Quaternion prevQ;

    void Start()
    {
    
    
       
        // 获取动画控件
        animator = this.GetComponent<Animator>();
        // 获取原始旋转
        prevQ = animator.GetBoneTransform(HumanBodyBones.LeftUpperArm).rotation;
        Quaternion currentQ = Quaternion.Euler(upperArm.x, upperArm.y, upperArm.z);
        animator.GetBoneTransform(HumanBodyBones.LeftUpperArm).rotation = currentQ * prevQ;
    }

    // Update is called once per frame
    void Update()
    {
    
    
        deltaz += 1f;
        upperArm.z = deltaz;
        Quaternion currentQ = Quaternion.Euler(upperArm.x, upperArm.y, upperArm.z);
        animator.GetBoneTransform(HumanBodyBones.LeftUpperArm).rotation = currentQ * prevQ ;
    }
}


ここに画像の説明を挿入

関連資料

https://blog.csdn.net/weixin_42348363/article/details/113685507
https://blog.csdn.net/weixin_44739495/article/details/110680128

更新する

この記事では単一レベルの回転操作のみを示し、次の記事では複数レベル オブジェクトの回転処理方法を記録します。

おすすめ

転載: blog.csdn.net/qq_43544518/article/details/125866072