最近在做一个根据配置表自动生成动画剪辑clip以及controller的功能.做法是根据配置表配置的动作以及每个动作的关键帧,自动为每个clip添加事件.这样做可以把动画的事件处理在游戏运行之前就计算好然后存到动画文件.anim中,可以提高游戏的运行效率,如果做的再细点,还可以自定义动画事件的传入的参数.比如act游戏中的多段攻击,这些数据一定是配到表中的,我们可以把表中的数据导入成Unity的ScriptableObject类型,然后打成.asset文件,在把他指定给AnimationEvent的objectReferenceParam参数,这样当动画播放的攻击帧并检测到攻击事件后直接把本段攻击的配置数据传入游戏运行时,可以减少不少的数据查找操作.

     private static void AddClipEvent(AnimationClip clip, ActionData data)
{
List atvts = new List();
float maxFrame = data.frameCount;
if (!string.IsNullOrEmpty(data.detFrames))
{
string[] dets = data.detFrames.Split(','); for (int i = 0; i < dets.Length; i++)
{
int frame;
if (int.TryParse(dets[i], out frame))
{
if (frame > 0 && frame <= maxFrame)
{
AnimationEvent detEvt = new AnimationEvent();
detEvt.functionName = GCharacter.FRAME_EVENT_NAME;
detEvt.stringParameter = GCharacter.FrameType.Detec.ToString() + "_" + data.id + "_" + i;
detEvt.time = frame / clip.frameRate;
atvts.Add(detEvt);
}
}
}
} AnimationEvent endEvt = new AnimationEvent();
endEvt.functionName = GCharacter.FRAME_EVENT_NAME;
endEvt.stringParameter = GCharacter.FrameType.End.ToString() + "_" + data.id;
endEvt.time = data.frameCount / clip.frameRate;
atvts.Add(endEvt); AnimationUtility.SetAnimationEvents(clip, atvts.ToArray());
}

不过在做到这的时候你会发现一个问题,那就是GCharacter.FrameType.End是最后一帧的帧事件,每当一个state切换到另一个state的时候这个帧尾的事件是不会被调用的!盯着Unity的状态机视图看了很久,终于找到了问题的所在!

Unity之所以收到很多人的青睐就是因为他给开发者实现了很多比较复杂的功能,这里就是因为两个动画过度时候的融合导致的,添加Transition的时候会默认指定一个过度时间,也就是上图中的Transition Duration,这里是0.1.

所以其实就相当于上个动画播放到距离最后一帧还有0.1秒的时候开始播放下一个动画,也就是此时Unity的"当前状态"已经是下一个state,而上一个state的后几帧的事件也不会触发.

有两种方法,一种是Transition Duration设为0,还有一种是让动画在离最后一帧还有0.1秒的时候就认为动画已经播放到最后一帧.我是用的后者,毕竟Unity"动画过度的融合"咱不能自己写吧,可是差0.1秒,到是可以在程序中自己控制.

把这句改成这样:endEvt.time = (data.frameCount / clip.frameRate) - 0.12f;

OK,完事!

本文固定连接:http://www.cnblogs.com/fly-100/p/5008961.html

Unity游戏开发——自动为动画剪辑添加事件 之 最后几帧的事件不能被调用的问题的更多相关文章

  1. 喵的Unity游戏开发之路 - 轨道摄像机

    前言        很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此我们精选了一套国外优秀的Unity3D游戏开发教程,翻译整理后放送给大家,教您从零开始一步一步掌握Unity3 ...

  2. 喵的Unity游戏开发之路 - 游泳

    原文: https://mp.weixin.qq.com/s/-ERFNB1GRZ6UAkHOhP9UQw 很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此我们精选了一套国外优秀 ...

  3. 喵的Unity游戏开发之路 - 互动环境(有影响的运动)

    如图片.视频或代码格式等显示异常,请查看原文: https://mp.weixin.qq.com/s/Sv0FOxZCAHHUQPjT8rUeNw 很多童鞋没有系统的Unity3D游戏开发基础,也不知 ...

  4. 【Unity游戏开发】记一次解决 LuaFunction has been disposed 的bug的过程

    一.引子 RT,本篇博客记录的是马三的一次解决 LuaFunction has been disposed 的bug的全过程,事情还要从马三的自研框架 ColaFrameWork 说起.最近,马三在业 ...

  5. Unity 游戏开发技巧集锦之创建透明的材质

    Unity 游戏开发技巧集锦之创建透明的材质 Unity创建透明的材质 生活中不乏透明或者半透明的事物.例如,擦的十分干净的玻璃,看起来就是透明的:一些塑料卡片,看起来就是半透明的,如图3-23所示. ...

  6. 【Unity游戏开发】不接SDK也能在游戏内拉起加QQ群操作?

    一.引子 一般在游戏进行对外测试的时候都会有一个玩家QQ群,方便玩家反馈问题.交流游戏心得等.那么为了增加玩家加QQ群的欲望,可能会在游戏里面设计一个小功能,点击一下可以直接拉起手Q加群的操作,加了Q ...

  7. 喵的Unity游戏开发之路 - 玩家控制下的球的滑动

  8. 喵的Unity游戏开发之路 - 在球体上行走

    很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此我们精选了一套国外优秀的Unity3D游戏开发教程,翻译整理后放送给大家,教您从零开始一步一步掌握Unity3D游戏开发. 本文不 ...

  9. 喵的Unity游戏开发之路 - 多场景:场景加载

    如果丢失格式.图片或视频,请查看原文:https://mp.weixin.qq.com/s/RDVMg6l41uc2IHBsscc0cQ 很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始 ...

随机推荐

  1. android屏幕适配方法

    android中图片适配是一件很棘手的事情,本篇文章详细的介绍屏幕显示的原理,为什么会资源文件中会存在 drawable-ldpi.drawable-mdpi.drawable-hdpi.drawab ...

  2. Python3基础 使用list() 生成一个空列表

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...

  3. Android4.0图库Gallery2代码分析(二) 数据管理和数据加载

    Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Androi ...

  4. 浏览器加载外部js 的顺序,以及处理顺序。

    问题, 有事候按F12打开 google的调试台后,查看network下面加载过来的资源是, 有些资源的状态处于 pending.. 个人理解: 浏览器是可以同时开启多个http 请求去加载外部的资源 ...

  5. Bundle display name 与 Bundle name 的区别

    Bundle display name 与 Bundle name 的区别是什么?"Bundle Name" and "Bundle display name" ...

  6. 计算机学院大学生程序设计竞赛(2015’12) 1006 01 Matrix

    #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> ...

  7. Xcode 6配置里定义${ARCHS_STANDARD}为armv7, arm64以及错误

    转发:http://www.cocoachina.com/ios/20141013/9897.html 最近一次的Xcode 6更新默认不再支持arm7s架构,究竟是要废除不用呢还是仅仅只是一个疏忽? ...

  8. iOS多页面传值方式之单例传值singleton

    // 要实现单例传值,那就必须得新建一个类做为单例 提供创建该类对象的类方法(因为是要在alloc开辟内存空间后赋值).所有在.h文件中声明该方法 + (instancetype)defaultUII ...

  9. CDbConnection failed to open the DB connection: SQLSTATE[28000] [1045] Access denied for user 'root'@'localhost' (using password: YES)

    连接mysql出错:CDbConnection failed to open the DB connection: SQLSTATE[28000] [1045] Access denied for u ...

  10. laravel database的事务函数

    laravel的事务使用如下: DB::connection('gvideo')->transaction(function () use ($user_id, $video_id, $acti ...