Unity アニメーション フュージョン IK MatchTarget ディレクター

深く理解していないのでメモを残す

アニメーションフュージョン

ステルス極秘作戦 14-17

新しいステートマシン

パネル上の動き

//モーション動作
//ロコモーション、動き、自分の名前
//ロコ、機関車
//ブレンド、混合
ここに画像の説明を挿入

通常のパネルアニメーションとの違い

//通常のアニメーションのモーションはアニメーションクリップです
ここに画像の説明を挿入

新しいビヘイビアツリー

// ダブルクリックして入力します
ここに画像の説明を挿入

アニメーションを追加する

//ノードをクリックします
//右側の最初の小さな円をクリックしてアニメーションを追加します
//アニメーション項目が十分でない場合は、下の「+」をクリックしてください
ここに画像の説明を挿入

(1Dの例) 歩くから走るまでスピードの大きさをコントロール

//右下隅にある他のモデルをドラッグできます
ここに画像の説明を挿入

効果

// サイズが 3M の GIF カードで FAX するのは簡単ではありません
ここに画像の説明を挿入

他のモデルを右下隅のウィンドウにドラッグできます。

ここに画像の説明を挿入

(2Dの例)

Unity TimeLine アプリケーション チュートリアル クールなオープニング アニメーション 23-31
//デカルト、デカルト
//1. 2D を選択し (任意の 2D、メイン効果を試してください)、パラメータを選択します (水平は水平/左を意味し、垂直は垂直/前後を意味します) //2. ランダムに選択します (角速度コントロールの左右は参照できるかもしれませんが、他の要素はどの要素を参照するかわかりません)。3 の効果がある限り、ランダムに選択します

ここに画像の説明を挿入

アニメーションのカット/調整

通常、モデルのすべてのアニメーションは一般的なクリップに配置され、カットされたか自分でカットされたかに関係なく、必要な状態のクリップが作成されます。






ここに画像の説明を挿入

角速度

// 角速度はステアリングに大きな影響を与えます
// 方向転換は、「カニ」が横に歩くのではなく、向きを変えることに依存します
ここに画像の説明を挿入

効果

ここに画像の説明を挿入

(問題) Animator が空で開きます

リブート

アンチウッド

Unity TimeLine アプリケーション チュートリアルのクールなオープニング アニメーション 43-47

FixAnimatorIKPositionAndRotation (ボーン部分、特定の位置、重み) [カスタム関数]

    [Tooltip("肩膀上的木头,一开始不激活")] public GameObject wood;
    [Tooltip("模型中左手腕处")] public Transform leftHand;
    [Tooltip("模型中右手腕处")] public Transform rightHand;
    //
    private void OnTriggerEnter(Collider other)//接触木头
    {
    
    
        if (other.tag == "Log")
        {
    
    
            Destroy(other.gameObject);
            print("碰撞");
            CarryWood();
        }
    }
    private void CarryWood()//扛木头
    {
    
    
        wood.SetActive(true);
        animator.SetBool(willHoldLogID,true);
    }
    private void OnAnimatorIK(int layerIndex)//每帧调用,需要层启用IK
    {
    
    
        if (layerIndex == 1)//对应HoldLog层
        {
    
    
            int weight = animator.GetBool(willHoldLogID) == true ? 1:0;//willHoldLogID的值

            FixAnimatorIKPositionAndRotation(AvatarIKGoal.LeftHand,leftHand, weight);
            FixAnimatorIKPositionAndRotation(AvatarIKGoal.RightHand,rightHand, weight);
        }
    }
    private void FixAnimatorIKPositionAndRotation(AvatarIKGoal target, Transform match, int weight)//使用match的位置角度来调整target
    {
    
    
        animator.SetIKPosition(target, match.position);//设置位置
        animator.SetIKRotation(target, match.rotation);
        animator.SetIKPositionWeight(target, weight);//设置优先级
        animator.SetIKRotationWeight(target, weight);
    }

最初のパラメータのボーン部分

AvatarIKGoal.LeftHand
AvatarIKGoal.RightHand は
、このレイヤーのステート マシンが左手と右手のみを使用することを意味します。他の部分はその制御下にありません
ここに画像の説明を挿入

2 番目のパラメータ、LeftHand/RightHand の位置

//具体的な操作は、木の下に 2 つの空のノードを作成し、「木への抵抗」中に左手と右手の Transform を保存することです。 //手を回転させて木にフィットさせ、効果を実現します。 //左手と右手の Transform を木の下の 2 つの空のノードに割り当て
ます
左手と右手のリセット
ここに画像の説明を挿入

3番目のパラメータIKはボーンの位置がターゲット(自分で設定)の位置のままであることを認識します

//原理は不明ですが、とにかく全て1(ターゲットの位置を特定)にしないと位置誤差が発生します
ここに画像の説明を挿入

メソッドパラメータの比較

Animator.SetIKPositionWeight
ここに画像の説明を挿入

ターゲット マッチ MatchTarget

壁の向こう

// 緑色のボールは次のコードによって生成されます

        animator.MatchTarget(matchTarget,
            Quaternion.identity,
            avatarTarget,
            new MatchTargetWeightMask(matchTargetWeightMask, 0),
            startTime,
            endTime
        );

ここに画像の説明を挿入

    private void Vault()//腾跃,尝试过和Slide重构复用,太麻烦
    {
    
    
        //1、播放动画
        //速度>3 && 是 LocalMotion行为树

            //射线检测
            float testDistance = 4f;//检测距离
            float vaultDistance = 3f;//起跳距离
            bool willVault = false;//是否要进行翻墙

            //rayPos,direction,射线,长度
            bool isHit = Physics.Raycast(transform.position+Vector3.up*0.3f, transform.forward, out RaycastHit hit, testDistance);
            if (isHit && hit.collider.tag == "Obstacle")//障碍物是墙
            {
    
    
                if (hit.distance > vaultDistance)//
                {
    
    
                    willVault = true;
                    //
                    Vector3 point = hit.point;
                    point.y = hit.collider.transform.position.y + hit.collider.bounds.size.y;//位置加自身高度
                    matchTarget = point;//得到着手点
                    matchTarget.y +=matchTargetOffsetY;
                }
            }          
            animator.SetBool(willVaultID, willVault);
        

        //2、MatchTarget
        //有一个状态叫ClimbOver && 在翻墙中, 不在状态切换过程中(差值)
        if (animator.GetCurrentAnimatorStateInfo(0).IsName("ClimbOver") && animator.IsInTransition(0) == false)
        {
    
    
            //1、MatchTarget
            float startTime = 0.3f;
            float endTime = 0.4f;
            MatchTarget(matchTarget, AvatarTarget.LeftHand, Vector3.one, startTime, endTime);
        }
    }
        void MatchTarget(Vector3 matchTarget,AvatarTarget avatarTarget, Vector3 matchTargetWeightMask, float startTime, float endTime)
    {
    
    
        //动画在(startTime,endTime)时
        animator.MatchTarget(matchTarget,
            Quaternion.identity,
            avatarTarget,
            new MatchTargetWeightMask(matchTargetWeightMask, 0),
            startTime,
            endTime
        );
    }

滑りやすい

//主にendTimeを調整します
//ビデオ matchTarget = hit.point+transform.forward * 2 (大きいほど遠く、エフェクトを見るときにビデオが10に設定され、スライドが遠くなります) // matchTargetは、(startTime, endTime)の期間内にモデル全体がどれだけ前に進むかを決定し
ます
ここに画像の説明を挿入

    void Slide()//滑地
    {
    
    
        //1、播放动画
        //速度>3 && 是 LocalMotion行为树
        if (animator.GetFloat(verticalID) > runSpeed && animator.GetCurrentAnimatorStateInfo(0).IsName("LocalMotion"))
        {
    
    
            //射线检测
            float testDistance = 4f;//检测距离
            float slideDistance = 2f;//滑地距离
            bool willSlide = false;//是否要进行翻墙


            //start,direction,射线,长度
            bool isHit = Physics.Raycast(transform.position + Vector3.up * 1.5f, transform.forward, out RaycastHit hit, testDistance);

            if (isHit && hit.collider.tag == "Obstacle")//障碍物是墙
            {
    
    
                if (hit.distance > slideDistance)//起跳距离
                {
    
    
                    willSlide = true;

                    //设置match
                    Vector3 point = hit.point;
                    point.y = 0;//滑行不影响高度
                    point = point + transform.forward*10;
                    matchTarget = point;//滑行个2米
                }                  
            }
            animator.SetBool(willSlideID, willSlide);
        }
          
        //
        if (animator.IsInTransition(0) == false && animator.GetCurrentAnimatorStateInfo(0).IsName("Slide"))
        {
    
    

            //1、MatchTarget
            float startTime = 0.38f;//0.17
            float endTime = 0.67f;//0.67f;//30
            //float startTime = 0.17f;//0.17
            //float endTime = 0.30f;//0.67f;//30
            MatchTarget(matchTarget, AvatarTarget.Root, new Vector3(1, 0, 1), startTime, endTime );
        }
    }
    void MatchTarget(Vector3 matchTarget,AvatarTarget avatarTarget, Vector3 matchTargetWeightMask, float startTime, float endTime)
    {
    
    
        //动画在(startTime,endTime)时
        animator.MatchTarget(matchTarget,
            Quaternion.identity,
            avatarTarget,
            new MatchTargetWeightMask(matchTargetWeightMask, 0),
            startTime,
            endTime
        );
    }

監督

public PlayableDirector director;//过场动画的相机,播放时间轴
    private void OnTriggerEnter(Collider other)//接触木头
    {
    
    
        if (other.tag == "Playable")
        {
    
    
            director.Play();//播放Timeline
        }
    }

ここに画像の説明を挿入
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_39538253/article/details/118282229