Animator & Timeline
Posted qqw123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Animator & Timeline相关的知识,希望对你有一定的参考价值。
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 using UnityEngine.Playables; 5 6 public class Player : MonoBehaviour { 7 8 private Animator anim; 9 //private int speedID = Animator.StringToHash("Speed"); //走 10 //private int isSpeedUPID = Animator.StringToHash("isSpeedUP"); //跑 11 //private int turnAroundID = Animator.StringToHash("TurnAround"); //转向 12 13 private int speedRotateID = Animator.StringToHash("SpeedRotate"); 14 private int speedZID = Animator.StringToHash("SpeedZ"); 15 16 private int isHoldLogID = Animator.StringToHash("isHoldLog"); 17 private int slideID = Animator.StringToHash("Slide"); 18 private int vaultID = Animator.StringToHash("Vault"); 19 private Vector3 matchTarget = Vector3.zero; 20 21 private CharacterController characterController; 22 private int colliderID = Animator.StringToHash("Collider"); 23 24 public GameObject unityLog = null; //角色身上的木头 25 public Transform rightHand; //木头左右边的节点(空的gameobject) 26 public Transform leftHand; 27 public PlayableDirector playable; 28 29 // Use this for initialization 30 void Start () { 31 anim = GetComponent<Animator>(); 32 characterController = GetComponent<CharacterController>(); 33 //unityLog = transform.Find("Reference/Hips/Unity_Log (1)").gameObject; //找到Log 34 } 35 36 // Update is called once per frame 37 void Update () { 38 //2D混合树控制移动和旋转 39 anim.SetFloat(speedZID, Input.GetAxis("Vertical") * 4.1f); 40 anim.SetFloat(speedRotateID, Input.GetAxis("Horizontal") * 126f); 41 42 ProcessVault(); 43 ProcessSlide(); 44 //if(anim.GetFloat(colliderID)>0.5f) 45 //{ 46 // characterController.enabled = false; 47 //} 48 //else 49 //{ 50 // characterController.enabled = true; 51 //} 52 //上面判断语句的简写 53 //滑动或FQ时禁用角色控制器 54 characterController.enabled = anim.GetFloat(colliderID) < 0.05f; 55 56 57 //走 58 //anim.SetFloat(speedID, Input.GetAxis("Vertical")*4.1f); 59 60 ////转向 61 //anim.SetFloat(turnAroundID, Input.GetAxis("Horizontal")); 62 ////跑 63 //if(Input.GetKeyDown(KeyCode.LeftShift)) 64 //{ 65 // anim.SetBool(isSpeedUPID, true); 66 //} 67 //if (Input.GetKeyUp(KeyCode.LeftShift)) 68 //{ 69 // anim.SetBool(isSpeedUPID, false); 70 //} 71 72 73 } 74 75 //FQ 76 private void ProcessVault() 77 { 78 //FQ 79 bool isVault = false; 80 //当Animator状态机在混合树“Motion”时判断,节省性能 81 if (anim.GetFloat(speedZID) > 3 && anim.GetCurrentAnimatorStateInfo(0).IsName("Motion")) 82 { 83 RaycastHit hit; 84 if (Physics.Raycast(transform.position + Vector3.up * 0.3f, transform.forward, out hit, 4f)) 85 { 86 if (hit.collider.tag == "Obstacle") 87 { 88 if (hit.distance > 3) 89 { 90 Vector3 point = hit.point; 91 //设定匹配位置 92 point.y = hit.collider.transform.position.y + hit.collider.bounds.size.y + 0.05f; 93 matchTarget = point; 94 isVault = true; 95 } 96 97 } 98 } 99 } 100 anim.SetBool(vaultID, isVault); 101 102 //匹配跳跃过程中左手与墙面的位置 103 if (anim.GetCurrentAnimatorStateInfo(0).IsName("Vault")) 104 { 105 anim.MatchTarget(matchTarget, Quaternion.identity, AvatarTarget.LeftHand, new MatchTargetWeightMask(Vector3.one, 0), 0.32f, 0.4f); 106 } 107 108 } 109 110 //滑 111 private void ProcessSlide() 112 { 113 bool isSlide = false; 114 if (anim.GetFloat(speedZID) > 3 && anim.GetCurrentAnimatorStateInfo(0).IsName("Motion")) 115 { 116 RaycastHit hit; 117 if (Physics.Raycast(transform.position + Vector3.up * 1.5f, transform.forward, out hit, 3f)) 118 { 119 if (hit.collider.tag == "Obstacle") 120 { 121 if (hit.distance > 2) 122 { 123 Vector3 point = hit.point; 124 point.y = 0; 125 matchTarget = point + transform.forward * 2; 126 isSlide = true; 127 } 128 } 129 } 130 } 131 anim.SetBool(slideID,isSlide); 132 if (anim.GetCurrentAnimatorStateInfo(0).IsName("Slide")) 133 { 134 anim.MatchTarget(matchTarget, Quaternion.identity, AvatarTarget.Root, new MatchTargetWeightMask(new Vector3(1,0,1), 0), 0.17f, 0.67f); 135 } 136 } 137 138 //检测碰撞 139 private void OnTriggerEnter(Collider other) 140 { 141 //木头 142 if(other.tag=="Log") 143 { 144 Destroy(other.gameObject); 145 CarryWood(); 146 } 147 //镜头 148 if(other.tag=="Playable") 149 { 150 playable.Play(); 151 } 152 } 153 154 //扛木头 155 void CarryWood() 156 { 157 unityLog.SetActive(true); 158 anim.SetBool(isHoldLogID, true); 159 } 160 161 //设置左右手IK到相应节点 162 //每帧都调用 163 private void OnAnimatorIK(int layerIndex) 164 { 165 //当layer层级为HoldLog 166 if(layerIndex==1) 167 { 168 int weight = anim.GetBool(isHoldLogID) ? 1 : 0; 169 //左手 170 anim.SetIKPosition(AvatarIKGoal.LeftHand, leftHand.position); 171 anim.SetIKRotation(AvatarIKGoal.LeftHand, leftHand.rotation); 172 anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, weight); //IK权重 173 anim.SetIKRotationWeight(AvatarIKGoal.LeftHand, weight); 174 175 //右手 176 anim.SetIKPosition(AvatarIKGoal.RightHand, rightHand.position); 177 anim.SetIKRotation(AvatarIKGoal.RightHand, rightHand.rotation); 178 anim.SetIKPositionWeight(AvatarIKGoal.RightHand, weight); 179 anim.SetIKRotationWeight(AvatarIKGoal.RightHand, weight); 180 } 181 } 182 }
Rig:
动画类型分为三类
1.Legacy:老版本的动画系统,一般都是单独做好的
2.Generic:骨骼动画,一般用在非人型生物上
3.Humanoid:骨骼动画,一般可通用在人形模型上面,只要骨骼节点设置相同
如果有些人物模型带有骨骼但是无法通用可选择:Create Form This Model -> Apply一下
->点击configure进行编辑确认后保存退出看下能不能用
Animation:
可进行动画的剪切与播放设置
1.Loop Pose让动画循环播放时衔接更顺滑(猜测是通过动画曲线开始与结束时的的陡峭程度进行插值运算)
2.Root Transform 下面的Bake into Pose勾选后动画播放后的位置就会被固定(有些动画播放时会有位移和转向)
3.Curves:设置曲线值,并且可以在Animator编辑器中添加相同名称的Parameters来控制触发条件
Animator状态机:
1.可以把动画拖进去设置然后通过相应的状态连接起来(点击连接箭头后如右边Inspector显示)
(1)Has Exit Time是否等当前动画播放完才跳转到下一个
(2)Conditions里可以设置Parameter里添加的各种条件参数
Blend Tree混合树:
在Animator里的BaseLayer层右键单击选择Creat State -> From New Blend Tree
如右边面板所示 (1)可选择1D/2D等混合树类型
(2)可以添加各个动画然后在图中拖动摆放各个动画并观察相互间的影响范围,也可以通过Compute Positions来按照特定条件计算摆放
以上是关于Animator & Timeline的主要内容,如果未能解决你的问题,请参考以下文章
from=timeline&isappinstalled=0 是啥意思