在一些Arpg里,翻滚是一个经典的动作,角色可以通过翻滚动作中的无敌帧来规避很多伤害。事不宜迟,马上想想如何实现这个激动人心的动作。
首先,添加动画,在添加完动画之后,我想要对现在动画的Transition做一些更改,主要是想模仿一下黑魂的动画安排,就是:
1.步行或闲置状态按空格是翻滚
2.在奔跑状态按空格是跳跃+翻滚
3.在下落状态时如果速度大于某值就在落地再接个翻滚
那么这节就考虑第一点如何实现。
目前的情况是:任何状态下按空格都是跳跃,想要在不同的速度下按空格获得不同的反馈,就要在Transition的Condition里把forward值考虑上
所以,在给ground到roll拉了Transition后,要在Conditions里加个forward值,且less 1.1。
除此之外,还要加个jump信号。然后还要在ground动画里调整一下Transition的优先权,调整为roll到jump再到fall,即在键入空格后,先判断forward值是不是小于1.1,如果是就转换为roll,否则就转换为jump。
这样,在步行时键入空格就会翻滚。
现在的翻滚还有很多缺点,看图就能看到,它能随意转向,且只能原地翻滚。所以,一如既往,要锁死输入和锁死速度,而且还要给冲量。
这次不能像之前那样在OnEnterState()里呼叫然后给冲量和锁死速度再放进movongVec里,因为现在不只是考虑步行时,还要考虑闲置进翻滚,闲置是没有锁死速度这个概念的,本来速度就是为0。如果在OnStateEnter()里给冲量,就会造成角色闲置进翻滚时是瞬移而不是配合翻滚动画移动。
所以要在翻滚动画进行时给它一个小冲量,让它逐渐慢慢往前移,这样配合动画就比较流畅,不过这样做蛮耗效能的,以后会有优化的方法。进行时就要用到OnStateUpdate()。在roll动画Add Behaviour,命名为FSMCallOnState,在里面敲入:
public string[] OnStateMessage;
override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
foreach (var msg in OnStateMessage) {
animator.gameObject.SendMessageUpwards (msg);
}
}
我想往上发的信息是OnRollState:
在ActorController.cs里:
void FixedUpdate(){
//rigid.position += movingVec * Time.fixedDeltaTime * walkSpeed;
rigid.velocity = new Vector3(movingVec.x,rigid.velocity.y,movingVec.z)+thrustVec;
thrustVec = Vector3.zero;
}
void OnRollState()
{
thrustVec = model.transform.forward * 1.0f; //我给的冲量是1.0
}
由于我在动画进行时给了一个冲量,所以就没有必要锁死速度了,但在进入roll时还是有必要锁输入:
void OnRollEnter()
{
pi.InputEnabled = false;
lockVelocity = false; //这个日后会提到
}
现在角色就能往自己面对的方向翻滚出一段距离且不会转向了:
如果感觉这个翻滚的动作有点离地或者这个动画播放的速度有点太快,可以通过编辑这个动画的Animation来调整:
我把角色自身的旋转信息和Y轴信息打进动画里,这样角色就不会在翻滚中根据动画的设定而进行旋转或Y轴的位移。例如我要是消勾Root Transform Position (Y),那么我的角色在翻滚时就会有离地的表现,因为它动画本身就是设计了有Y轴的变化:
但我觉得这并不好看,所以把角色自身的Y轴信息合并在动画里(Bake Into Pose),勾上的效果可以看上一张gif。