AnimationUtility.GetAnimationEvents获取的动画片段信息中time和SerializedObject对象中保存的time字段信息的区别

今天的工作中原本是需要做一个小工具来批量给某些动画加上一个事件,也就是AnimationEvent这货。查了一下官方文档,也Google了一番,最终在这里找到一个比较符合我需求的解决方案,方案是由Unity Technologies的童鞋提供的,看上去还是蛮靠谱的,传送地址在这里

我也就果断拿过来用了,当然前提还是我们自己需要做一番修改的,因为我的需求是只需要在原有的AnimationClip已有的AnimationEvent列表的最后面添加一个OnSkillEnd的AnimationEvent,所以我需要先获取到已有的AnimationEvent信息列表,这里我就想着直接用AnimationUtility.GetAnimationEvents方法来搞定了,而且我看到前面提到的Unity Technologies的童鞋也是这么做的,那么我也就想着这么搞应该就OK了。

不过事实证明这样还是有问题的,因为通过AnimationUtility.GetAnimationEvents获得的AnimationEvent信息列表中得所有AnimationEvent实例中的time字段确实是触发时间,也就是动画播放的具体时间,是绝对时间。而Unity实际保存到动画FBX文件对应的meta文件中的time字段是相对动画播放进度,可以认为是相对时间。

当我们使用文本方式打开动画FBX的meta文件时,我们会发现在这个YAML文件中有一个events节点,这个节点下面保存的就都是这个AnimationClip上绑定的所有AnimationEvent信息,我们找到time字段看一下就会发现,所有Event节点中的time字段都小于等于1.0,然后我们再通过AnimationUtility.GetAnimationEvents方法将AnimationClip中的AnimationEvent信息读取出来,我们会发现,这个AnimationEvent中time实际上就是等于meta文件中的time字段(动画播放进度百分比)乘以AnimationClip的完整时长。

我们可以看一段YAML文件:

events:
      - time: .0572792366
        functionName: OnSkillTrigger
        data: a_ke_zhan_attack_1#0
        objectReferenceParameter: {instanceID: 0}
        floatParameter: 0
        intParameter: 0
        messageOptions: 0
      - time: .143198088
        functionName: OnSkillTrigger
        data: a_ke_zhan_attack_1#1
        objectReferenceParameter: {instanceID: 0}
        floatParameter: 0
        intParameter: 0
        messageOptions: 0
      - time: .393794745
        functionName: OnSkillTrigger
        data: a_ke_zhan_attack_1#2
        objectReferenceParameter: {instanceID: 0}
        floatParameter: 0
        intParameter: 0
        messageOptions: 0
      - time: .744630039
        functionName: OnSkillTrigger
        data: a_ke_zhan_attack_1#3
        objectReferenceParameter: {instanceID: 0}
        floatParameter: 0
        intParameter: 0
        messageOptions: 0

所以为了避免出现使用实际时间来作为相对时间保存,我们可以选择自行换算或者直接采用同一个标准进行计算,例如我们读取的时候采用直接读取SerializedObject对象中的SerializedProperty来获取time字段,保存的时候也通过SerializedObject对象中SerializedProperty来设置新的time字段就可以了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据