编写一个事件组件。
1.模仿 AnimationEvent 编写一个 StateEvents 类
2.用户可以创建一个指定时间、指定状态触发的事件类
3.事件可以采用反射机制,调用调用客户的方法;或使用订阅发布方法调用客户的方法。
4.在你的动画控制程序中使用 StateEvents 类
简而言之,我们需要实现的是一个能存储状态机动画中各个状态中的事件帧。并在对应的时间里执行对应的事件。用户使用接口只需要提供状态的名字(string)和触发的时间(float)以及调用的函数。各个类之间的对应关系:
每一个Animator对应一个状态机,对应多个状态,每一个状态机对应一个StateEvent,每一个StateEvent里面包含多个MyEvent,在这里MyEvent代表的是某个状态下某个时间点下所有的事件帧。对于StateEvent,我们给定一个特定的状态,我们可以得到一个MyEvent的List,分别对应不同时间点的所有事件。每一个MyEvent包含一个StateTrigger,用来判断是否触发这个MyEvent里的事件。MyEvent使用观察者模式实现。
工厂类
因为每一个animator对应一个stateEvent,我们可以使用工厂来实现,防止一个animator对应多个stateEvent。工厂类的实现如下:
StateTrigger
接下来是MyEvent中使用的辅助类StateTrigger,触发器是一个辅助类,他用一个float来初始化他要执行的时间,根据时间大小的比较来判断是否触发,触发后更改状态,在下一次相同状态再次初始化状态。
MyEvent
然后是辅助类MyEvent,这个类的作用是用来保存同一个状态下的同一时间下的所有事件帧,因此他有一个触发时间的属性,以及一个成员函数触发器,这个触发器用来判断这个事件是否到达要执行的时间。使用观察者模式来实现调用所有事件函数。
stateEvent
主类stateEvent,根据状态机的状态string来获取哈希值,来建立一个状态对应List的字典。当要添加一个新的事件帧时,先判断这个状态下是否有事件帧,如果没有,先创建一个新的list容器,如果有,那么遍历这个容器,看看相同时间下是否已经有对应的MyEvent,如果有,那么直接使用,否则新建一个。
状态更新函数:如果当前状态和久状态不同,那么调用enterstate表示进入新状态,如果相同,那么根据时间的运行状况,判断是否有事件帧需要执行。
脚本类
最后是脚本类:将挂载该脚本的对象的anmiator对象获取工厂中对应的StateEvent对象,执行他的update函数。
测试脚本:
完整代码