在制作动作游戏的时候,需要播放许多动画,同时还有个需求,那就是动画播放到一定时间时,给一个回调函数,好做对应的状态变更,
我查了一下,发现如果使用的是unity自带的动画系统,要做到这样的话,需要这样做:
1 public void AddCallBackOnClip(Type classType,AnimationClip clip,string callbacMethod,int callBackFrame,string sParam="",int iParam = 0,float fParam = 0f) 2 { 3 if (string.IsNullOrEmpty(callbacMethod)||clip==null) 4 { 5 return; 6 } 7 else 8 { 9 var methodByName = classType.GetMethod(callbacMethod); 10 11 if (methodByName==null) 12 { 13 Debug.LogError(string.Format("在{0}类中,找不到名为{1}的方法", classType.Name, callbacMethod)); 14 return; 15 } 16 else 17 { 18 var timer =Time.deltaTime*callBackFrame; 19 20 Debug.Log("timer=" + timer); 21 22 if (timer>clip.length) 23 { 24 return; 25 } 26 27 AnimationEvent evt = new AnimationEvent(); 28 29 evt.functionName = callbacMethod; 30 evt.intParameter = iParam; 31 evt.floatParameter = fParam; 32 evt.stringParameter = sParam; 33 34 evt.time = timer; 35 36 clip.AddEvent(evt); 37 } 38 } 39 }
通过以上代码可以看到,其实对于绑定回调函数,是传入的回调函数名字,而并没有使用类似于C#委托一类的东西,那么问题来了,这个只是传入方法的名字的字符串,到底是怎么确认到底该绑定哪个类里面的方法呢?
通过实验,我发现是这样子的,对于上面给出的一个绑定方法,是在哪一个Mono脚本中调用,就会去绑定哪一个Mono脚本中对应的方法。
举个例子,假设 物体Go上挂了脚本 A和脚本B,两个都拥有一个叫做PrintMsg()的方法,工具类C 中实现了 AddCallBackOnClip()方法
那么现在在脚本A 中调用 AddCallBackOnClip() 方法,最后的结果是, A 和B 中的PrintMsg均会被调用,并且无论PrintMsg()是公有的还是私有的。
这就很坑爹了!所以在使用Unity的这个功能时一定要小心,不然就很容易不知道问题出在哪儿了。
除却上述坑爹的地方之外,还有一个小小的问题,那就是可以看到,事件回调只能通过指定 时间 来绑定,而不能通过指定 动画具体帧数来绑定,
这样出现的问题是,可能不会那么精确,会存在一些小小的误差。不过这一点,相对来说是可以接受的。