一、动画状态机控制

1、导入人物动画,调整为人形动画,做好前期准备工作(修改动画是否循环,动画范围,动画旋转锁定,Y轴,XZ轴锁定等)

2、添加Animator组件,创建动画状态机

android动画旋转中心 动画设置进入旋转_android动画旋转中心

3、打开动画状态机,把人物待机、走路、跑步、向左跑、向右跑的动画添加到状态机中。

4、添加参数Speed、ISRun、TurnRun/移动速度、是否跑步、转向速度

android动画旋转中心 动画设置进入旋转_权重_02

android动画旋转中心 动画设置进入旋转_权重_03

android动画旋转中心 动画设置进入旋转_权重_04

android动画旋转中心 动画设置进入旋转_权重_05

android动画旋转中心 动画设置进入旋转_状态机_06

android动画旋转中心 动画设置进入旋转_android动画旋转中心_07

android动画旋转中心 动画设置进入旋转_状态机_08

android动画旋转中心 动画设置进入旋转_android动画旋转中心_09

 二、混合树Blend Tree

1、1D混合树控制一个方向运动

在Animator面板下创建BlendTree,双击BlendTree进入编辑界面

android动画旋转中心 动画设置进入旋转_ide_10

2、2D混合树通过两个变量控制,一个使用速度控制PosY,另一个是用角度控制PosX

android动画旋转中心 动画设置进入旋转_ide_11

 三、功能代码

1.相机跟随移动

 

1  public Transform playerTran;//目标人物
 2     Vector3 offset;
 3     float smoothing=2;
 4     private void Start()
 5     {
 6         offset = transform.position - playerTran.position;//相机位置与人的位置差
 7     }
 8     private void Update()
 9     {
10         Vector3 targetPosition = playerTran.position + playerTran.TransformDirection(offset);
11         transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * smoothing);
12         transform.LookAt(playerTran.position);
13     }

 

 

 

public class PlayerAnimationController : MonoBehaviour
{
    public Animator playerAni;
    int speedID = Animator.StringToHash("Speed");
    int IsRunID = Animator.StringToHash("IsRun");
    int turnRun = Animator.StringToHash("TurnRun");
    void Update()
    {
        playerAni.SetFloat(speedID, Input.GetAxis("Vertical"));//控制移动
        playerAni.SetFloat(turnRun, Input.GetAxis("Horizontal"));//控制转向
        if (Input.GetKeyDown(KeyCode.LeftShift))//控制是否加速
        {
            playerAni.SetBool(IsRunID, true);
        }
        else if (Input.GetKeyUp(KeyCode.LeftShift))
        {
            playerAni.SetBool(IsRunID, false);
        }
    }
}

四、控制人物FQ

1、将修改完的FQ动画添加到状态机中,新添加变量SpeedX、SpeedY、IsOverTheWall

android动画旋转中心 动画设置进入旋转_android动画旋转中心_12

 

2、添加功能

int speedX = Animator.StringToHash("SpeedX");//转向的速度
  int speedY = Animator.StringToHash("SpeedY");//前进的速度
  int IsOverTheWall = Animator.StringToHash("IsOverTheWall");//FQ
  bool isOverTheWall = false;//是否FQ
  private Vector3 margetPosition=Vector3.zero;//FQ匹配的位置
  //FQ
    void PlayerVault()
    {
        isOverTheWall = false;
        playerAni.SetFloat(speedX, Input.GetAxis("Horizontal") * 126);
        playerAni.SetFloat(speedY, Input.GetAxis("Vertical") * 3.6f);
        if (playerAni.GetFloat(speedY) > 2 && playerAni.GetCurrentAnimatorStateInfo(0).IsName("Locomotion"))
        {
            RaycastHit hit;
            if (Physics.Raycast(transform.position + Vector3.up * 0.3f, transform.forward, out hit, 4))
            {
                if (hit.collider.tag == "Obstacle")
                {
                    if (hit.distance > 3)
                    {
                        Vector3 point = hit.point;
                        point.y = hit.collider.transform.position.y + hit.collider.bounds.size.y + 0.1f;
                        margetPosition = point;//目标位置
                        isOverTheWall = true;
                    }
                }
            }
        }
        playerAni.SetBool(IsOverTheWall, isOverTheWall);
        if (playerAni.GetCurrentAnimatorStateInfo(0).IsName("Vault") && playerAni.IsInTransition(0) == false)
        {
             //指定了匹配的位置、角度、身体的具体部位、权重、匹配开始时间和结束时间
            playerAni.MatchTarget(margetPosition, Quaternion.identity, AvatarTarget.LeftHand, new MatchTargetWeightMask(Vector3.one, 0), 0.32f, 0.4f);
        }
    }

3、给人物添加CharacterController,在动画状态机中新添加变量Collider来控制播放FQ动画是角色控制器与墙不发生碰撞

4、设置FQ动画下Curves,先确定两帧(开始FQ和结束FQ),编辑两个点大于0.5,并把设置的Collider变量放置在Curves上

android动画旋转中心 动画设置进入旋转_权重_13

5、效果展示

android动画旋转中心 动画设置进入旋转_android动画旋转中心_14

五、控制人物滑动

1、将修改完的滑动动画添加到状态机中,新添加变量Slider控制是否滑动

2、动画状态机连接情况如图

android动画旋转中心 动画设置进入旋转_权重_15

3、添加功能代码

int slider = Animator.StringToHash("Slider");//滑动
 int playcollider = Animator.StringToHash("Collider");
 void Update()
{
        PlayerSlider();
        PlayerVault();

        playerCharacterController.enabled = playerAni.GetFloat(playcollider) < 0.45f;
}
 //滑动
 void PlayerSlider()
{
        bool IsSlider = false;
        if (playerAni.GetFloat(speedY) > 2 && playerAni.GetCurrentAnimatorStateInfo(0).IsName("Locomotion"))
        {
            RaycastHit hit;
            if (Physics.Raycast(transform.position + Vector3.up * 1.5f, transform.forward, out hit, 3))
            {
                if (hit.collider.tag == "Obstacle")
                {
                    if (hit.distance > 2)
                    {
                        Vector3 point = hit.point;
                        point.y = -10;
                        margetPosition = point + transform.forward * 2;
                        IsSlider = true;
                    }
                }
            }
        }
        playerAni.SetBool(slider, IsSlider);
        if (playerAni.GetCurrentAnimatorStateInfo(0).IsName("Slide") && playerAni.IsInTransition(0) == false)
        {
            Debug.Log("滑动");
            playerAni.MatchTarget(margetPosition, Quaternion.identity, AvatarTarget.Root, new MatchTargetWeightMask(new Vector3(1, 0, 1), 0), 0.17f, 0.67f);
        }
    }

4、同样也给滑动动画下Curves添加Collider,在播放动画时关闭角色控制器

5、效果展示

android动画旋转中心 动画设置进入旋转_权重_16

  

 六、动画状态机Layers层设置

Weight:1(对其他层的动画的影响权重值,1:完全影响(如果Blending为Additive的话,那么会将所有层的Additive的Weight的值进行同时计算),0:完全不影响)

Mask:HandWaveLMask(下面有图,我们只要保留左手绿色即可)

Blending:Override(该层的动画将会覆盖其他的)

android动画旋转中心 动画设置进入旋转_ide_17

1、举木头动画切换

android动画旋转中心 动画设置进入旋转_权重_18

android动画旋转中心 动画设置进入旋转_权重_19

android动画旋转中心 动画设置进入旋转_权重_20

2、由于举木头动画与移动动画有影响,创骨骼遮罩在Projects——>Avatar Mask设置骨骼遮罩

android动画旋转中心 动画设置进入旋转_状态机_21

android动画旋转中心 动画设置进入旋转_权重_22

3、通过IK设置左右手位置,与木头更加吻合

勾选上图中IK Pass,添加两个点是左右手位置

代码如下:

1   public Transform leftHandPos;//左手位置
 2   public Transform rightHandPos;//右手位置
 3   int holdLog = Animator.StringToHash("IsHoldLog");//是否举起
 4  private void OnTriggerEnter(Collider other)
 5     {
 6         if (other.tag=="Wood")
 7         {
 8             Destroy(other.gameObject);
 9             CreateWood();
10         }
11     }
12     //显示木头
13     void CreateWood()
14     {
15         newWood.SetActive(true);
16         playerAni.SetBool(holdLog, true);
17     }
18     //通过IK动画设置举木头手的位置
19     private void OnAnimatorIK(int layerIndex)
20     {
21         float Weight = playerAni.GetBool(holdLog) ? 1 : 0;
22         if (layerIndex == 1)
23         {
24             //左手
25             playerAni.SetIKPosition(AvatarIKGoal.LeftHand, leftHandPos.position);//设置左手位置
26             playerAni.SetIKPositionWeight(AvatarIKGoal.LeftHand, Weight);//设置左手权重
27             playerAni.SetIKRotation(AvatarIKGoal.LeftHand, leftHandPos.rotation);//设置左手旋转
28             playerAni.SetIKRotationWeight(AvatarIKGoal.LeftHand, Weight);
29             //右手
30             playerAni.SetIKPosition(AvatarIKGoal.RightHand, rightHandPos.position);
31             playerAni.SetIKPositionWeight(AvatarIKGoal.RightHand, Weight);
32             playerAni.SetIKRotation(AvatarIKGoal.RightHand, rightHandPos.rotation);
33             playerAni.SetIKRotationWeight(AvatarIKGoal.RightHand, Weight);
34 
35         }
36     }

4、效果如图

android动画旋转中心 动画设置进入旋转_状态机_23