Unity动画☀️7. 通过MatchTarget匹配跳墙动画、Vector3、获取动画层GetCurrentAnimatorStateInfo(a).IsName(b)

2024-08-14 16:11:11 浏览数 (2)

1️⃣ 关键代码释义

a、Vector3

代码语言:javascript复制
// x = 0,y = 1, z = 0
Vector3.up;// 表示世界坐标系中 Y 轴正方向上的单位向量

// x = 0,y = -1, z = 0
Vector3.down; // 表示世界坐标系中 Y 轴负方向上的单位向量

// x = -1,y = 0, z = 0 
Vector3.left; // 表示世界坐标系中 X 轴负方向上的单位向量

// x = 1,y = 0, z = 0 
Vector3.right; // 表示世界坐标系中 X 轴正方向上的单位向量

// x = 0,y = 0, z = -1
Vector3.back; // 表示世界坐标系中 Z 轴负方向上的单位向量

// x = 0,y = 0, z = 1
Vector3.forward; // 表示世界坐标系中 Z 轴正方向上的单位向量 

// x = 0,y = 0, z = 0
Vector3.zero; // 表示原点

b、Animator.GetCurrentAnimatorStateInfo(a).IsName("b")

确定当前第a层动画的名字是不是b,是布尔型变量;Animator代指当前获取到的物体的动画控制器Animator,需要自己去获取这个组件,下同

c、

代码语言:javascript复制
Animator.MatchTarget(Vector3 matchPosition,Quaternion matchRotation,AvatarTarget targetBodyPart,MatchTargetWeightMask weightMask,float startNormalizedTime,float targetNormalizedTime)

1)、Quaternion.identity:同一性旋转(只读)。该四元数,相当于"无旋转":这个物体完全对齐于世界或父轴,是指Quaternion(0,0,0,0),就是每旋转前的初始角度,是一个确切的值

2)、AvatarTarget targetBodyPart:让身体的哪一个部位与目标位置保持一致

3)、MatchTargetWeightMask(Vector3 positionXYZWeight,float rotationWeight):身体的这一部位与目标位置的匹配度,Vector3 positionXYZWeight位置权重中的每个数字,0代表不匹配,1代表完全匹配,rotationWeight旋转权重类似

4)、startNormalizedTime & targetNormalizedTime:分别代表动画开始匹配的时间和结束匹配的时间

2️⃣ 控制逻辑:

通过MatchTarget()(将动画与场景匹配,使动画更逼真),将左手位置与墙上一点位置(计算得出)相匹配,跳跃时将两者重合,达到人机匹配结果

代码语言:javascript复制
using UnityEngine;

public class Player : MonoBehaviour {

    private Animator anim;
    private int speedRotateID = Animator.StringToHash("SpeedRotate");
    private int speedZID = Animator.StringToHash("SpeedZ");
    int vaultID = Animator.StringToHash("Vault");
    private Vector3 matchTarget;  //用来匹配目标点

    void Start () {
        anim = GetComponent<Animator>();
	}
	
	void Update () {

        anim.SetFloat(speedZID, Input.GetAxis("Vertical") * 4.5f);
        anim.SetFloat(speedRotateID, Input.GetAxis("Horizontal")*126);

        if (anim.GetFloat(speedZID) > 3 && anim.GetCurrentAnimatorStateInfo(0).IsName("LocalMotion"))
        {
            RaycastHit hit;
            if(Physics.Raycast(transform.position Vector3.up*0.3f,transform.forward,out hit, 4.5f))
            {
                if (hit.collider.tag == "Obstacle")
                {
                    if (hit.distance > 3)
                    {
                        Vector3 point = hit.point;
                        point.y = hit.transform.position.y  hit.collider.bounds.size.y 0.09f;  //普通的cube在水平面时默认中心高度y=0.5,但此模型水平中心高度为0(和底边一致)!,所以是它最低点位置 Y轴的大小
                        matchTarget =point;

                        anim.SetBool(vaultID, true);
                    }
                    
                }
            }
            else anim.SetBool(vaultID, false);
        }

        if (anim.GetCurrentAnimatorStateInfo(0).IsName("Vault"))
        {
            anim.MatchTarget(matchTarget, Quaternion.identity, AvatarTarget.LeftHand, new MatchTargetWeightMask(Vector3.one, 0), 0.32f, 0.4f);
        }
	}
}

3️⃣ 动画展示

大家还有什么问题,欢迎在下方留言!

0 人点赞