1.新增动画控制器吧
在assets目录下面新建animator文件夹,然后新建animator controller
你需要在window-animator下面唤出视窗,然后把心仪的动作拉进去
然后你需要在右侧的controller里面挂上你想要的那个动作才行
关于apply root motion:如果你希望按照动画来运动,那就勾选,如果想自己控制它的移动,那就不勾选
2.做一个动作混合树来让动作变得更加丝滑,管理更容易吧
在animator界面右键create state->new blend tree
比如我把这个blend tree重命名为groud,然后把所有在地面上执行的动画全部塞进去了
你可以在parameters里面修改滑条的名称

这个界面是用来干什么的,其实就是让你的动画变得不那么僵硬,可以以一个逐渐变化的方式开始运动,滑条为0就是不动,滑条为1就达到最大速度
你需要在右边的motion栏add两个 field motion
把待机动作添加到第一个motion里面,行走动作添加到第二个motion里面吧
很明显forward栏从0到1就是从静止到运动的变化过程,它变得更丝滑了

3.来了解一下混合树的类型吧
1d:受一个parametor调控
2d:受两个parameter调控
4.把控制器和动画串联起来吧
首先需要新建一个c#文本,然后取得animator
简单复习一下泛型吧,如果你要赋值到一个物品上面的时候,那么泛型表示一个占位符,意思是找你需要的那种类型
比如private Animator anim; void Start() { anim = model.GetComponent<Animator>(); }
这里的意思就是在model里面找一个Animator类型的组件哦
关于[SerializeField]:在变量上一行写了这句话,你就可以让想要的类型出现在unity编译器里面,但是必须是unity支持的类型才行
`public class ActorController : MonoBehaviour
{
// Start is called before the first frame update
public GameObject model;
public PlayerInput pi;
[SerializeField]
private Animator anim;
void Awake()
{
anim = model.GetComponent
pi=GetComponent
}
// Update is called once per frame
void Update()
{
anim.SetFloat("forward",pi.DirectionUp);
}
}
5.改变模型朝向的语句model.transform.forward=pi.DirectionRighttransform.right+pi.DirectionUptransform.forward;`
它相当于直接简单地用左速*左+右速乘以右边(其中transform.right,forward都是坐标)用以计算一个vector3的方向来改变模型朝向
6.rigidbody来控制人物运动吧
首先就是enable你的rigidbody吧,然后初始化,注意rigidbody绝大部分时候都不会再update方法里面更新,而是在fixedupdate里面运行
7.来让你的人物动起来吧。
这里主要是实现了几个逻辑,需要注意的是控制移动动作平滑的值和控制坐标(速度)的值是不同的值,但是他们都需要和和directionmag相关联,这个directionmag是通过横向和纵向的运动数值的平方相加开根号得到的,控制平滑的值需要改变animator里面你定义的那个滑杆的值,而移动则是需要改变坐标,这里设置了一个跑步的键位,如果按下这个键,那么滑杆的值会变成两倍,而跑步的坐标变化定义了一个新的multifyer用来倍增,你当然可以定义这个值,然后改变坐标的值是在fixedupdate里面实现,改变了了rigidbody的position值,你需要使用乘了multifyer的改变的坐标(速度)*时间。
`public class ActorController : MonoBehaviour
{
// Start is called before the first frame update
public GameObject model;
public PlayerInput pi;
[SerializeField]
private Animator anim;
private Rigidbody rigid;
private Vector3 movingVec;
public float speed=2.0f;
public float multifyer;
void Awake()
{
anim = model.GetComponent
pi=GetComponent
rigid=GetComponent
}
// Update is called once per frame
void Update()
{
if(pi.DirectionMag>0.1f){
model.transform.forward=pi.DirectionVector;
}
if(pi.run==true){
anim.SetFloat("forward",pi.DirectionMag2.0f);
movingVec = pi.DirectionMagmodel.transform.forward speedmultifyer;
}
else{
anim.SetFloat("forward",pi.DirectionMag);
movingVec = pi.DirectionMag*model.transform.forward *speed;
}
}
void FixedUpdate(){
rigid.position+=movingVec*Time.fixedDeltaTime;
}
}`
8.实现平滑的转向和跑步动作吧
`public class ActorController : MonoBehaviour
{
// Start is called before the first frame update
public GameObject model;
public PlayerInput pi;
[SerializeField]
private Animator anim;
private Rigidbody rigid;
private Vector3 movingVec;
public float speed=2.0f;
public float multifyer;
void Awake()
{
anim = model.GetComponent
pi=GetComponent
rigid=GetComponent
}
// Update is called once per frame
void Update()
{
if(pi.DirectionMag>0.1f){
Vector3 targetForward=Vector3.Slerp(model.transform.forward,pi.DirectionVector,0.3f);//使用slerp让目前的方向沿着平滑的改变转到目标方向
model.transform.forward=targetForward;//滑杆有特别明显的改变才会更新方向
}
if(pi.run==true){
float targetRunSpeed=2.0f;
anim.SetFloat("forward",pi.DirectionMagMathf.Lerp(anim.GetFloat("forward"),targetRunSpeed,0.02f));//改变滑杆数值
movingVec = pi.DirectionMagmodel.transform.forward speedmultifyer;//获取坐标值(速度)相当于用斜边长乘以方向的一个向量
}
else{
anim.SetFloat("forward",pi.DirectionMag);
movingVec = pi.DirectionMag*model.transform.forward *speed;
}
}
void FixedUpdate(){
rigid.position+=movingVecTime.fixedDeltaTime;//速度时间来改变位置,本质还是一个坐标方向向量乘以时间
}
}`
浙公网安备 33010602011771号