- 好友
- 12
- 在线时间
- 486 小时
- 最后登录
- 2024-12-18
子爵[版主]
- UID
- 2893127
- 第纳尔
- 14847
- 精华
- 0
- 互助
- 93
- 荣誉
- 21
- 贡献
- 325
- 魅力
- 1382
- 注册时间
- 2017-11-5
鲜花( 431) 鸡蛋( 0)
|
本帖最后由 vegetto 于 2023-3-7 07:45 编辑
前言:https://bbs.mountblade.com.cn/thread-2096174-1-1.html首先到我此贴学习下顶点动画的基础理论。
然后下载本次分享的md3顶点动画资源作为参考但未经我允许不可随意用于你们自己的mod【链接:https://pan.baidu.com/s/1XbZUyHzFMJ5BZ126I354IA?pwd=7456
提取码:7456
--来自百度网盘超级会员V5的分享】
本期分享动画包含了一个直升机动画,一个鱼鹰机动画(螺旋桨飞行,门和降落板动画),一个警戒塔的待机+破坏动画(前3个网盘给了视频预览,后面懒得录),一个书本翻页动画,一个更细节的旗帜动画,一个留声机运行动画和一个吊顶的电风扇旋转动画,为md3格式并提供相关贴图,并且我把每个动画模型提供了两套模型和贴图,看我的txt说明,我是把动画模型包含多贴图的留给你们一个多贴图状态的组合模型和利用插件合并贴图为一张后的整体模型。你们看大地图的顶点动画图标要求图标模型和贴图为一个整体,所以掌握合并贴图的技巧也很重要。
首先md3我没有导入brf中,给你们自己导入操作印象会更深刻一些,首先按照我下面图示用openbrf导入md3模型,然后选中模型点“编辑”后点“复制帧”,选项卡会消失,在选中模型前提下再次点开“编辑”选项卡,黏贴“时间信息”,来使得选中的动画模型参数信息列表里图示区域两个数据(5:50)处即(帧序:帧时刻)两个数据成10倍的等差数列关系,因为我上面理论贴已说明我们代码控制的是帧时刻,刚导入时帧序(0,1,2,3.。。)对应的帧时刻可能均为0可能是散乱的,所以必须进行此操作使得帧序(0,1,2,3.。。。)对应帧时刻(0, 10, 20, 30.。。。)才能保证播放动画时相邻两个帧序保持一样的时间间隔达到匀速播放的稳定控制效果。至于移动位置放大缩小模型这些操作不用我讲了吧,多放一些常用参考物体对比下尺度移动到合适位置。
这些是前期工作,下面一些实用的场景物品顶点动画操控实例:
一些实用的场景物品顶点动画操控实例( 第一期)生活用品类
对于有功能性的场景物来说,我们一般采用预设和刷的方式,比如我们放置可运走的机枪或者位置不固定的直升机的可自发运动的对象在空旷的战场区域以及需要被人拿着携带着的情况,有时会采用spawn sceneprop 像刷兵一样按照一定排列然后随机放置到场景里,而像有些起到装饰类或者对摆放区域特定要求的,比如风扇和留声机,风扇得和吊顶契合,留声机要找个台子放上面,这种就要编辑模式预设放置好。
而这两种情况对于我们这些顶点动画的初始化会带来处理的微小区别。
(假设下面所有涉及的含顶点动画的场景物名称叫spr_xxx)
操作情况大类一、
比如留声机和电风扇,采用编辑模式预设到场景的情况时,我们控制他的动画一般考虑下面这样做法(假设以下控制的对象场景里均只有1个):
以风扇为例
电风扇参考动画模型关键帧20个,如果你按我前言说的在openbrf中的处理操作,有效帧时刻会在0-190的区间内(注意我为什么说有效,仔细看我上面理论贴讲的,没有动画的场景物可以获取和控制当前帧时刻状态,谈有效则针对真正做了动画关键帧对应的帧时刻区间)
0.00000,0.00000,1000000.00000这种一次触发的条件中(代码实例1)
(scene_prop_get_instance, ":var_0", "spr_xxx", 0), #获取电风扇spr xxx的物体实例id":var_0"
(2612, ":var_0", 0, 190, 500), #令这个电风扇在0-190帧时刻播放循环动画,每次循环时间0.5秒(500/1000秒)
这样风扇因为一次触发条件初始进行了全序列的动画循环。
而在
0.00000,0.00000,0.00000这种持续触发的条件中(代码实例2)
(scene_prop_get_instance, ":var_0", "spr_xxx", 0),
(2616, ":var_1", ":var_0"), #获取电风扇当前的0帧时刻为":var_1"
(try_begin),
(neg|gt, ":var_1", 190), #这一块意思就是如果已经在帧时刻10-190播放动画,则对电风扇不触发10-190循环动画的指令,反之则触发。为什么要这么限制,因为你时时刻刻下同一个2612的循环动画命令会使得动画一直在起点帧时刻状态,为什么是neg|gt要取到190,因为2612循环动画是可以播放到末尾帧时刻190的
(ge, ":var_1", 10), #为什么不从0开始,因为默认载入场景帧时刻在0上,直接else下面被永久屏蔽了,而你动画制作精细的画放弃0关键帧也没事,而且很多动画制作的习惯就是首尾状态一致。
(else_try),
(2612, ":var_0", 10, 190, 500),
(try_end),
类似的留声机和翻页书本你单纯的放在酒馆的茶几上也是类似的操作,修改相应的动画区间即可。
以上是单纯循环一次动画点缀场景的过程。
接下来讲一下只含一个动作的循环动画+条件性打断的案例:
比如电风扇在吊顶,及留声机和翻页书本已经放桌上按上面的触发进行了循环动画,但是这些加上一个停止/启动运行的条件控制。
假设这个条件是全局变量$a,$a为0时电风扇关闭,为1时电风扇开启,
0.00000,0.00000,0.00000这种持续触发的条件中(代码实例3写法1)
(scene_prop_get_instance, ":var_0", "spr_xxx", 0),
(2616, ":var_1", ":var_0"),
(try_begin),
(eq, "$a", 0),
(2610, ":var_0", 0), #或改为 (2612, ":var_0", 0, 0, 500),亦可
(else_try),
(neg|gt, ":var_1", 190),
(ge, ":var_1", 10),
(else_try),
(2612, ":var_0", 10, 190, 500),
(try_end),
也就是多加了紫色段的代码,意思就是$a在风扇关闭的取值时,用2610操作动画模型状态强制到0这个固定帧时刻上,或者2612在0-0首位帧时刻相同的区间上播放动画,这样你的模型形态固定便不呈现旋转的动画。
而此时对于$a在0,1的取值上则另行判断,你可以是按了某个键盘键位,也可以是到控制电风扇的墙上的开关来一个F读条等等等等,并且$a你也可以是slot eq/ge这种条件或者具体按键或多条件复合等等,这个就不细讲,自由发挥。
但是如果你可以理解我说的有效帧时刻的概念,还可以这么写(代码实例3写法2):
(scene_prop_get_instance, ":var_0", "spr_xxx", 0),
(2616, ":var_1", ":var_0"),
(try_begin),
(eq, "$a", 0),
(try_begin),
(neg|gt, ":var_1", 250),
(ge, ":var_1", 200),
(else_try),
(2612, ":var_0", 200, 250, 500),
(try_end),
(else_try),
(eq, "$a", 1),
(try_begin),
(neg|gt, ":var_1", 190),
(ge, ":var_1", 0),
(else_try),
(2612, ":var_0", 0, 190, 500),
(try_end),
(try_end),
上面这段代码的前提是载入场景后$a的条件默认取值为0,对应你的模型动画处理有两种理解方式,一个是如果你的风扇动画只做了0-190的有效区间,那么播放200-250区间时模型的动画状态会维持190这个最后有效帧时刻的模型形态。第二种理解是,如果是做了200-250区间的有效动画,并且这个动画符合我上面说的“停止旋转”的动画状态,那么以上代码依旧能达到我提出的效果。所以请好好理解有效动画帧时刻的概念,这个抽象上可以用的很灵活。
对于预设放好的留声机翻页书本也是类似做法。
操作情况大类二、
特别的,对于翻页书本动画模型,如果我是要求被酒馆某个人拿在手上漫不经心的连续翻页,并且随着手部骨骼动画一起移动。
那么这种具有自发和被人物绑定被动运动关系的物品可以不用预设,采用刷的方式加入场景。
对于我提供的翻页书本参考动画模型共28帧,按我前言的处理后,有效帧时刻应该在0-270这个区间
假如酒馆看书的只有一个叫trp_xxx的人,可进行如下编码(代码实例4)
(set_fixed_point_multiplier, 1000),
(get_player_agent_no, ":var_0"),
(agent_get_position, pos1, ":var_0"),
(scene_prop_get_num_instances, ":var_1", "spr_xxx"),
(try_begin), #以下try范围内代码表示场景物可翻页的书本数量为0时刷一个出来备用
(eq, ":var_1", 0),
(copy_position, pos2, pos1),
(position_move_z, pos2, -10000),
(set_spawn_position, pos2),
(spawn_scene_prop, "spr_xxx"),
(2612, reg0, 0, 270, 500), #注意这种用spawn主动刷的物体,初始化动画或其他性质自定义参数可采用场景物实例id为reg0的写法进行快速初始化设定,这就和上面提前预设到场景的场景物初始动画设置用法有所区别
(scene_prop_set_slot, reg0, 200, -8), #给这个场景物定性,认定是同一个类别的物体,方便以后在其他触发器需要try for prop时方便集中控制
(try_end),
(scene_prop_get_instance, ":var_5", "spr_xxx", 0),
(try_for_agents, ":var_3"),
(agent_is_alive, ":var_3"),
(agent_is_human, ":var_3"),
(agent_get_troop_id, ":var_4", ":var_3"),
(eq, ":var_4", "trp_xxx"),
(agent_get_bone_position, 3, ":var_3", 19, 1), #获取目标agent人右手武器点(骨骼编号19)的骨骼坐标为pos3
####此处略去一些postion move xyz/ rotate xyz坐标微调操作自己把握
(prop_instance_set_position, ":var_5", pos3),
(try_end),
这样酒馆场景里一个trp xxx的人便会一直拿着spr xxx这个书本并持续翻页动画。
如果需要条件性阻止翻页或隔一会翻一会可以参考(代码实例3),自己琢磨这个条件和结果怎么互相干预的。
类似的举一反三,我提供的含有500多帧更细致的旗帜动画也可以参考类似将场景物位置设置到手武器骨骼坐标一起运动的做法。
然后一些比较复杂的案例,后续第二期开始再陆续举例并提供相关动画资源参考
|
|