上节我们解决了jump到fall的Transition,这节解决第二个Transition。
2.fall到ground的转换
同样,二话不说先拉个Transition,从fall到ground的。
fall→ground
然后考虑这个Transition的HasExitTime,因为在角色到达地面后(isGround为true),无论fall动画是否播放完毕,都应该停止并转换回ground,所以要消勾HasExitTime。然后再考虑触发这个转换的Condition,显然就是isGround这个布尔值,这里不难理解,不再解释。
到此这个转换大致就完事了,但还有一些细枝末节需要处理,我们可以上坡然后从高处跳下来看看那个效果。
可以看到起跳的时候这个角色的下落轨迹是一开始有点弧度,然后竖直下落,这显然是不应该的,正常来说应该整个下落轨迹是一条弧线就好看一点。我们先分析目前的下落轨迹是怎么造成的:
1.开始有一丢丢的弧度
这是因为前某一节处理跳跃时锁死速度造成的。
2.之后呈直线下落
这是因为跳跃动画播放完了呼叫了OnJumpExit()函数使得速度取消锁死,而后续fall动画没相应处理造成的。
分析得知,我们应该在fall动画做同样锁死速度的处理。步骤只做简要的说明,因为之前已经有了详细的步骤解析。
步骤为1.在fall动画上Add Behaviour两次分别命名为FSMCallOnEnter和FSMCallOnExit,因为之前就已经创建这两个脚本文件,所以可以直接拿来用,用的是相同代码的副本文件,并不是同一个文件。
2.在FSMCallOnEnter上OnStateEnter()上发送信息为OnFallEnter,这段代码文件里面就有的了,不用动,因为之前就已经创建过这个文件的了。
public class FSMCallOnEnter : StateMachineBehaviour {
public string [] onEnterMessage;
// OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
foreach (var msg in onEnterMessage) {
animator.gameObject.SendMessageUpwards (msg);
}
}
}
OnFallEnter
3.在FSMCallOnExit上的OnExitEnter()上发送信息为OnFallExit(),同理代码已有。
4.在ActorController.cs文件里接收信息:
void OnFallEnter(){ //当进入下落状态时
pi.InputEnabled = false;
lockVelocity = true; //当跳跃时锁死速度,不让速度归0
}
我们理想当然的这么做,也理想当然的认为会有结果,当初我是这么想的,但是发现没有得到与之符合的结果,人物依旧是一开始时的下落轨迹,没有变化。即lockVelocity并没有开启。我开始寻思,是不是OnFallEnter()函数并没有被正确调用到?于是我在OnFallEnter()里print一些信息,以验证这个问题:
void OnFallEnter(){ //当进入下落状态时
print("sdfsdfasfsadf16516");
pi.InputEnabled = false;
lockVelocity = true; //当跳跃时锁死速度,不让速度归0
print("sdfsdfasfsadf");
}
结果发现是有输出的:
这证明OnFallEnter()是有被调用的,这就奇了怪了,为什么调用了,而lockVelocity却没改变?我百思不得其解,只好放弃使用OnFallEnter()亦或是OnJumpExit()其中一个,希望日后能找出原因。现在只能另找出路。
于是乎我想,OnJumpExit()是离开跳跃触发,它要做的是把之前的锁死输入和速度恢复原样,而离开跳跃只能转向fall或ground,转向fall的话是要锁死输入和速度,回到ground的话要恢复原样,要不取消OnJumpExit()?然后把这两个分开实现。试试看,现在OnFallEnter()已经做好了,剩下的是回到ground,我可以在ground动画里Add Behaviour,增加一个FSMCallOnEnter,在里面实现OnJumpExit()要做的事,在进入地面状态后恢复输入和速度的变化,这样的话不仅是OnJumpExit()可以取消了,甚至OnFallExit()也可以取消了,因为fall最终只会回到ground。
OnGround
void OnGround(){ //当进入地面状态时
pi.InputEnabled = true; //开启输入
lockVelocity = false; //恢复速度变化
}
我们可以看看效果如何:
可以了,这就是我想要的效果,虽然心路历程曲折了点,且有一个疑问没有解决,但还好做出来了。
网友评论