1.跑步功能
把run动画的Threshold改成2,这样到forward到2会自动跑步
下面我们用脚本调用这个动画 :
先在PI里加入下面的代码
public string keyA;//按键操作
public string keyB;
public string keyC;
public string keyD;
public bool run;//是否要run
update里调用:
run = Input.GetKey(keyA);
然后再ActorController里调用
public float runMultiplier = 2.0f;
update里:
anim.SetFloat("forward", pi.Dmag * (pi.run? 2.0f:1.0f));//完美和动画控制器的forward一致
movingVec = pi.Dmag * model.transform.forward * walkSpeed*(pi.run? runMultiplier : 1.0f);//通过变量修改。
这节学到了,加run动画,用bool判定是否会run,这是个持续的过程,按keyA时会执行,在Update里 的setfloat加上(pi.run? 2.0f:1.0f) 就能完美与动画控制器对接,舒服,然后在movingVec里实现run加速的情况,并命名了一个ruMultiplier参数调速。
2.线性插值和球形线性插值
解决2个问题一个是转弯太唐突了(转弯就是球形插值Slerp),一个是从走逃跑太唐突了。
update下线性插值改变快速变2的情况
anim.SetFloat("forward", pi.Dmag *Mathf.Lerp(anim.GetFloat("forward"),targetRunMulti,0.5f));
插值改变快速转向的情况
if(pi.Dmag > 0.1f)//如果没有这个限制,转到其他方向松手它还是会自动转回0, 有这个限制条件就不会自动转回了。
{
Vector3 targetForward = Vector3.Slerp(model.transform.forward, pi.Dvec, 0.3f);//用这个插值使得转向有个30%的延迟
model.transform.forward = targetForward;//方向就是存量X方向向量,这样你的转向就会朝向这个方向动
}
3.椭圆映射法
https://arxiv.org/ftp/arxiv/papers/1509/1509.06344.pdf这里面有转换的数学方法。
PI:用这个方法把DupDright的Y,X值改成圆形的X,Y值的方法
PI:这样就好了。
4.一次性触发事件
做跳跃
PI:
我们只需要前面的绿色部分所以newJump == true就是那个限制条件。
学到了一次触发的方法。理解了其中的原理。
5.加入跳跃动画
添加跳跃动画到初始层
ActorController:这边有个隐性问题,unity的trigger如果连续按多次,jump会叠加一次。
6.巧妙的重置控制器的触发。
在动画控制器下ground上创建一个脚本FSMClearSignals
控制器界面:这样的话连续按2次jump的话,控制器就不会再储存一次了。
7.FSMOnEnter和FSMOnExit方法
这个脚本什么意思呢,这个脚本是挂在jump动画里的,意思是进入这个脚本后会开始发送一个信息给Animator组件的上级的gameobject里的脚本发一个信号msg,
就是OnJumpEnter信号,用PlayerHandle下的任意一个脚本做一个方法
public void OnJumpEnter()
{
print("onJumping!!!");
}
public void OnJumpExit()
{
print("我松开了jump ");
}
unity就会实现print的输出。
这样做的意义就是,当进入或者离开jump的状态时可以让脚本调用一些方法使它适合的跳跃,可以用脚本实时的控制动画的播放问题了。我们就可以解决角色在空中也可以跳可以转向的情况了。PS:sendmessage这个是可以优化的
8.锁死平面移动
如果执行这个,会导致Dmag,和Dvec=0,这样的话,
planarVec = pi.Dmag * model.transform.forward * walkSpeed * (pi.run ? runMultiplier : 1.0f);
在ActorController这个update方法下会一直重复调用这个方法每秒60次,那么planarVec就一定是持续不能动的一直是0,你就会发现人物被所在跳的那个位置执行动画,这时候如果加lockPlanar当你跳的时候不让它更新就可以了,就会顺其自然的跳了。很简单吧。
AC:
private bool lockPlanar=false;//继续更新速度,ture时不更新了,就不会一直为0了
if(lockPlanar ==false)//当为true时,锁死原来的planarVec的值不更新它。
{
planarVec = pi.Dmag * model.transform.forward * walkSpeed * (pi.run ? runMultiplier : 1.0f);
}
public void OnJumpEnter()
{
pi.inputEnabled = false;
lockPlanar = true;
}
public void OnJumpExit()
{
pi.inputEnabled = true;
lockPlanar = false;
}
inputEnabled虽然在update里,但是他是一个条件句
重新思考了下
当你跳的时候,调用inputEnabled = false 这样会导致速度和方向全是为0 ,并且每秒更新60次,这样看到的结果就是原地播放动画,转向和速度都是0。
现在加一个lockPlanar来限制inputEnabled里的速度不要持续为0,就是让速度向量消失,这样就不会一直让他执行速度0的操作了,于是你会发现主角会有跳跃向前的速度,但是期间不能改变方向。