- 好友
- 12
- 在线时间
- 486 小时
- 最后登录
- 2024-12-18
子爵[版主]
- UID
- 2893127
- 第纳尔
- 14847
- 精华
- 0
- 互助
- 93
- 荣誉
- 21
- 贡献
- 325
- 魅力
- 1382
- 注册时间
- 2017-11-5
鲜花( 431) 鸡蛋( 0)
|
本帖最后由 vegetto 于 2023-1-10 14:02 编辑
首先是到人场景物各系统的运动行为控制总章https://bbs.mountblade.com.cn/thread-2094109-1-1.html先看一下各系统运动控制的基础用法。本贴作为其中一个具体应用大类特别拎出来讲下。
关于骑砍中模拟人、马、各种动物包括地上跑的水里游的天上飞的、飞机坦克战舰及其同类机械载具、以及不同对象的配合活动比如马车以及坦克要载人这种。并没有把其中很多对象的运动和其他使之像个“活体”的行为处理到尽善尽美或者存在技术瓶颈,或者玩家还行ai有些僵了等等情况。
并且大多数时候,我们把这些不同对象的处理到程序时,持一种分开研究的观念。实际上我们要先联系去对待不同运动对象的各种行为控制,因为人和其他生物都是一个祖先演化的,机械工具也是根据各种生物启发而作为人类器官的功能延申,所以他们都有一种共性的地方然后部分进行条件限制产生分化。
可以先看看我的顶点动画控制系统https://bbs.mountblade.com.cn/thread-2096174-1-1.html,以上不同生物机械对象可以采用不同系统换皮比如人、马、场景物这些具备位移和其他行为的代码控制的系统来模拟。对于要场景物控制的,如果还要借助其动画,其实就跟用正常游戏引擎一样,要在一穷二白的基础上写人物的移动这些基本控制,因为你们大多习惯了mod这种沿用系统本身托管的运动机制,所以熟悉下,如果你在引擎裸奔的情况下,怎么把一个死物处理成一个活物。
看完之后对以下几个不同的生物机械对象的运动及其他行为控制特性和方法展开分析:
研究对象选择:【 (人)、 (马、坦克)】、【(鸟、直升机)、飞机】、【(鱼、潜艇)、船】、炮
看我这样的写法,用(【对这些对象进行了一下运动特性相似程度的分类。
一、首先是对各类对象可以采用的模拟系统:
1、对于正常生活的普通人可采用的系统机制及组合:
(1)纯agent机制(固有机制+模型换皮)
(2)纯场景物机制(像基础引擎一样从0开始写位移动画等事件,需要制作并控制顶点动画)
(3)agent(辅)与场景物(主)联动机制(可以隐藏目标agent形态,以场景物的模型外形代表整体的样子,保留利用agent的位移和其他ai行为指导场景物跟随运动、播放顶点动画、攻击等等,这种就看我顶点动画控制章节贴对于我魔兽争霸mod人物的控制例)
2、对于马等陆地动物及坦克、鱼、船可采用的系统机制及组合:
(1)纯马机制(多用于与马四肢爬行动物差别较小的对象,固有机制+模型换皮,特殊动物或车类微调骨骼动画,有时结合no dynamic阉割固有机制位移或放开z轴位移限制)
(2)纯agent机制(与马四肢爬行动物差别较大的对象,调整骨骼或微调动画的,有时结合no dynamic阉割固有机制位移或放开z轴位移限制)
(3)纯场景物机制(像基础引擎一样从0开始写位移动画等事件,需要制作并控制顶点动画)
(4)agent或马(辅)与场景物(主)联动机制(可以隐藏目标agent或马的形态,以场景物的模型外形代表整体控制对象的样子,保留利用agent的位移和其他ai行为指导场景物跟随运动、播放顶点动画等等)
(5)agent或马(主)与场景物(辅,多以碰撞形式)联动机制(基本原理和纯agent和纯马机制类似,但是给予碰撞体跟随包裹,比如给马换皮的坦克提供collision类型的真实碰撞体)
以上多用于单体模拟,如果是载具含人的多人模拟,还有如下两种机制:
(6)agent或马与场景物多重联动机制(agent或马和场景物在外观显示和运动等机制方面存在一对多,多对一,多对多的混合控制,难分主次,每个部分共同完成对象机制的一部分功能,比如我先用影身的agent控制出坦克/飞机一样的位移行为,再套上一个场景物坦克/飞机的模型,在场景物坦克/飞机的相对位置套上一些副驾驶;或者我纯粹从0编写坦克/飞机移动ai不依靠agent的运动等ai机制,然后再绑定多个agent骑手分工;以及坦克/飞机存在多个可动的零配件等情况)
(7)多个agent的多重联动机制(比如https://bbs.mountblade.com.cn/thread-2096142-1-1.html我的骨骼拼接理论,男上加男思想,假如agent拟化为其他生物,再利用dynamic状态控制3d空间运动来构造人骑人或人用人的情况,然后将其中一个人骨骼特殊化为其他生物或武器工具)
3、对于适应不同题材的人可采用的系统机制及组合:
对于真实生活的普通人位移行为比较有限,但是存在于小说影视剧的人位移行为可以说能够囊括(马、坦克)、【(鸟、直升机)、飞机】、【(鱼、潜艇)、船】、炮这些,进而按照第2点的(1)-(7)思路编写相关位移功能,因为科幻魔幻题材中你作为人可以飞,作为人鱼或者水性好的人可以像船一样水面游也可以潜入深海像鱼像潜艇更可以水上漂直接脚踩步行于水面,然后修仙者的飞行等等空中移动行为,以及允许取消一些正常碰撞判定的限制进行遁地术穿墙术等等。
4.然后对于以上的不同对象不同机制,如何把各个系统对模拟各种对象的运动机制搞好,我们主要的需要掌握的几个代码类控制要点是:
(1)agent与场景物的无障碍运动控制,简称主动运动控制:即move/Rotate的平移旋转与set /animate pos的位移设置,不同dynamic状态对场景物/agent的重力即Z轴运动的限制,agent自身特殊的scripted_destination强制目的地和ai行为的综合,需要掌握各种操作最适宜的场合。
(2)障碍物对agent与场景物运动反馈控制,简称碰撞判定修正运动:即参考对象运动到障碍物是停止还是撞击毁灭还是反弹还是左右上下磨蹭错开出去,以及在地面行走时是像人一样保持与世界oxy平面垂直还是像车一样平行于地面坡面。就像我这个自定义图案阵型系统https://bbs.mountblade.com.cn/thread-2094179-1-1.html提过的,碰撞检测的几种手段之一,除了胶囊的op判断,坐标点集合的距离判断,castray的射线判断,in sight视线范围或者屏幕坐标超出屏幕范围的视线模糊判断,特殊的对地形的高度值ground level获取判断,需要掌握各种操作最适宜的场合。 然后你要记住,碰撞判断是为了干啥的,要么是为了影响运动,要么是为了判断打击范围,所以对于运动修正来说,你需要参考生活实际和你自己的想法,比如人按W键前进蹭到墙上,产生的碰撞判断条件是阻止W键的前进位移量,还是会产生类似AD的左右位移量辅助人物把自己挤出来,还是你的人会飞檐走壁,自动产生z轴向上的位移量,等等。也就是以碰撞判断的条件去改变主动位移控制,加入其他方向的被动位移分量去消弱增强或消失wasd这种主动位移控制的基础效果。
(3)最后是一切你觉得这个运动对象应该具备的ai行为对运动的影响:比如攻击开炮是否需要停止位移,攻击行为是自己从0基础重写机制根据位置角度时间计算,还是借助已有agent的ai获取行为指导(类似场景物和agent的视角是否存在关系,是否用agent需要攻击的倾向来触发场景物的add missle或其他行为)等等等等
二、对不同类运动研究对象的动画动作行为对运动的影响分析:
首先对于一切要动起来的对象,基本事件就像我顶点动画系统控制写的那样,无非是idle(待机发呆型动作)、walk/RUN/fly(基础移动类动作)、attack(攻击类动作)、skill(可以是技能也可以是一些技巧动作)、under attack(受到攻击的动作)、death(死亡动作)。
每个基础动作可以一个(比较少)也可以是多个并列级的随机或根据一定条件选择。
运动首先离不开动作和行为事件(有动画的动作是具体的动作,而一些抽象的行为事件引发运动是抽象的动作事件,为什么这么说,你们玩过魔兽争霸编辑器可能就知道,魔兽争霸的触发器就是时间-条件-动作,也就是执行什么行为都叫动作行为,所以对动作这个概念我们也要广义的理解,比如理解为广义的怎么行动。),所以对不同动作事件与运动即位移行为的关联作出分析:
1、对于idle待机动作是很多游戏的对象单体动画动作之起始和中转,无论如何都少不了的动作,就是我在顶点动画控制写的,如果非idle动作的条件结束不能支持其继续执行这个动作行为,那最终会播放完当前动作后会回归idle的循环动作,比如你想想你人攻击后停止按左键以及走路突然不按wasd,是不是就开始自动播放idle站立备战或叉腰类型的等待动作,马也是。这时候idle动作下就会终止研究对象的位移行为。
对于如何主动和被动的终止各种对象的位移,比如人和马这种agent系统,且对于玩家自身的agent控制来讲,按照原有系统你不按wasd或没有障碍物推你或没有跳楼自由落体,你就不会位移。但是如果我要主动控制,某个条件下你在四周开阔脚落地的情况下按了wasd也不准动。这时候你可以靠 agent_set_no_dynamics, ":var_1", 1),这种操作,还有次一点的使用高频的agent_set_scripted_destination和agent set position,但一般不可取,因为agent set position由于人主动转向的系统ai行为与之高频联合运用有的时候会鬼畜原地晃动并影响人碰撞hitbox的判断,agent_set_scripted_destination因为是让ai自由在自己和目的地之间的路径跑,没有强制立即停止自身位移,并且可以被攻击和障碍物再次打退当前位置。
至于为什么我要人和马这种agent系统主动在本应该移动的时候停止移动呢,这种运用场合比较多,比如我要要ai做特定行为时需要保持原位不受wasd按键干扰,以及换皮,没错,就是比如说马换皮坦克,或者马和人影身后设置一个坦克飞机伴随运动时,偷个懒不完全重写ai移动,部分借助agent的运动机制时,根据表象对象即我们需要展示的坦克和内核对象我们辅助运动的agent,之间运动的差别来进行位移阉割,目的是为了屏蔽系统托管的位移控制,加入自己编写的部分新位移控制。这个具体我在下面run动作行为中再展开说。
2. 对于RUN基础移动类动作,虽然上面几个研究对象有海陆空位移能力都占或部分占的,但是如果用主动类位移控制代码来,都大同小异。
对于上下左右前后六向位移来说:
路上跑的最常见,控制最轻巧,且要和天上飞的对象联系起来看,因为陆地走的和天上飞的两类研究对象最基本的运动特性差别就是向下向上的位移受限的程度,是agent机制的对象想要自由被代码主动控制六向移动可以靠agent_set_no_dynamics操作的dynamic状态+碰撞判定终止一些条件下的位移,如果是场景物机制的对象六向位移本身自由+碰撞判定(包含地面判定,对不会飞的物体)终止一些条件下的位移,比如水里游的,你就是海平面线上wasd等按键控制水平或有限竖直范围(河底到水面)的位移,所以关键是获取水面基础高度或者你可以构造一个prop碰撞面与水面基准重合辅助判定。
但是对对象的位移再次细分,
人和马的基础位移有什么差别:你自己控制时感受感受,人wasd时多数情况速度可以保持差不多,as侧移时不晃动鼠标可以基本保持面向向前的模型姿态来左右移动,而马as侧移的时候你会发现,身体模型需要向侧移的方向有较大幅度的转动,再比对坦克装甲车这种,左右侧移时也不会让它出现保持面向朝前然后左右平移的这种运动,而是要使得整个面向向侧移方向同时旋转运动。并且对于马和车来说运动感受的惯性效果比较明显,以及后退的速度(或后退起步阶段)明显慢于前进时。
所以说为什么要分析这些不同类对象的运动差异,就是本身这些对象在选取agent还是场景物prop系统以及进行换皮组合即以人或马的皮套另一个人或马的运动控制内核,人或马皮套场景物prop的运动控制内核,场景物prop皮套人或马的运动控制内核这三种换皮情况时,怎么考虑屏蔽该运动控制内核默认支持的会导致人不像人、马不像马、车不像车、鸟不像鸟的位移操作,并保留仿人像人、仿马像马、仿车像车、仿鸟像鸟的位移操作。
接下来先进入基础运动控制代码实例分析环节,
对【 (人)、 (马、坦克)】、【(鸟、直升机)、飞机】、【(鱼、潜艇)、船】、炮进行运动代码基础和后续分化的各阶段讲解,因为idle和run,即代表静止和运动的行为,我们学物理都知道,静止是运动的一种特殊状态,运动停了就是静止,所以基础的运动控制必须把运动和静止的关联条件触发写清。
首先研究对象均以prop来模拟这些生物,为什么,因为prop是控制最自由的,默认不会受到碰撞阻力重力作用,所以用prop写出各种对象的运动特征,那么agent运动控制也不再话下,所以下面就算是agent的人我也要夺舍用prop模拟一遍运动控制给你们看看:
首先把我运动总章https://bbs.mountblade.com.cn/thread-2094109-1-1.html贴的第一回复楼的实例2代码拎出来看看,以下是让场景物不受碰撞重力阻力动画控制等限制前提下,可以根据wasd r ctrl这六个按键并结合鼠标晃动的视角转向进行前左右后上下六个方向的匀速位移。然后我示范一下对里面怎么改动,可以把整个代码区分成分别运动行为相似于【 (人)、 (马、坦克)】、【(鸟、直升机)、飞机】、【(鱼、潜艇)、船】、炮这些不同对象:
(0.000000, 0.000000, 0.000000,
[
],
[
(get_player_agent_no, ":var_0"), #知道为什么都场景物运动了,我还要获取玩家干什么,看下面两个copy rotation了解我的目的
(agent_get_position, pos1, ":var_0"), #玩家的坐标,实时获取
(scene_prop_get_num_instances, ":var_10", "spr_dragon"), #判断spr_dragon这个要控制的场景物有几个,对应下面的只控制刷一个
(try_begin),
(eq, ":var_10", 0),
(set_spawn_position, pos1),
(spawn_scene_prop, "spr_dragon"), #以上意思就是spr_dragon数量为0就在玩家的位置pos1刷一个出来,主要就是场景物如果没有事先放置,你就要给刷一个,数量就是控制执行一次的条件。
(try_end),
(eq, ":var_10", 1),
(scene_prop_get_instance, ":var_1", "spr_dragon", 0), #飞行的对象就是spr_dragon这个场景物
(prop_instance_get_position, pos2, ":var_1"), #场景物的坐标,实时获取
#(agent_set_no_dynamics, ":var_0", 1), #引申做法1: 也就是我前面讲的把agent和prop的运动优势结合。把深蓝字体的#注释去掉,通过场景物影其形,只留其运动控制与agent人之形结合。 这样prop物的自由六向控制就嫁接给了agent人。
#(scene_prop_set_visibility, ":var_1", 0), #场景物影身
#(agent_set_position, ":var_0", pos2), #agent和prop位置协同
(try_begin),
(this_or_next|key_is_down, key_w),
(this_or_next|key_is_down, key_a),
(this_or_next|key_is_down, key_s),
(this_or_next|key_is_down, key_d),
(this_or_next|key_is_down, key_v),
(key_is_down, key_left_control),
(agent_get_look_position, pos4, ":var_0"),
(position_copy_rotation, pos1, pos4),
(else_try),
(position_copy_rotation, pos1, pos2),
(try_end), #上面这段要配合下面镜头控制前的copy_rotation看,你们玩游戏有没有注意一个细节,就是玩家打人移动时镜头是视角方向,但是如果玩家站立不同,晃动鼠标旋转可以上下查看周身
(try_begin),
(key_is_down, key_w),
(position_move_y, pos2, 80),
(else_try),
(key_is_down, key_a),
(position_move_x, pos2, -80),
(else_try),
(key_is_down, key_s),
(position_move_y, pos2, -80),
(else_try),
(key_is_down, key_d),
(position_move_x, pos2, 80),
(else_try),
(key_is_down, key_r),
(position_move_z, pos2, 80),
(else_try),
(key_is_down, key_left_control),
(position_move_z, pos2, -80),
(try_end), #以上是为了让玩家在按r ctrl adws,上下左右前后将场景物的坐标按此方向移动80,但是首先运动时基准角度是玩家的视角方向,这样可以进行俯冲仰冲等等360度无死角自由的多向移动。所以涉及到运动旋转转弯的时候,巧用 (position_copy_rotation, 移动坐标, 视角坐标),的坐标复制十分便捷
(prop_instance_animate_to_position, ":var_1", 2, 5), 最后一个参数速度随你们调,不过我一般直接不写,因为我现在是高频触发,animate的运动效果的均匀化对我前面的位移控制影响不大,但是会降低移动速度,也就是animate不写参数和setpos还是有区别的,不写因为系统0.000触发还有微弱时间间隔。
(try_begin),
(neg|key_is_down, key_w),
(neg|key_is_down, key_a),
(neg|key_is_down, key_s),
(neg|key_is_down, key_d),
(neg|key_is_down, key_r),
(neg|key_is_down, key_left_control),
(agent_get_look_position, pos3, ":var_0"),
(position_copy_rotation, pos2, pos3),
(try_end), #这个就是我上面解释的,为了保证玩家运动时镜头平行视角能360度自由飞行,静止时可以晃动鼠标查看周身。
(try_begin),
# (scene_prop_set_visibility, ":var_1", 0), #将场景物影身
(position_rotate_x, pos2, 10), #引申应用2: 游戏摄像机镜头控制功能,假如把深蓝色字体的位移修正代码用#注释禁用,再把浅蓝色的字体代码#注释符号拿掉启用,在场景物的pos2设置摄像机,则场景物位置即为摄像机位置,如果场景物影身或者本身就定义成不具备外表的空模型,那么控制场景物便是控制摄像机镜头
(position_rotate_z, pos2, -15),
(position_move_y, pos2, -125), #数值根据场景物的体型和性质调整
(position_move_z, pos2, -10), #数值根据场景物的体型和性质调整
(position_move_x, pos2, -15),
(mission_cam_set_mode, 1), #设为1摄像机将像agent场景物一样自由控制位置,否则就是你们常见的固定在肩部。后面我建议如果该场景物具备飞行和着陆条件,镜头位置应该分开写,因为着陆后的视野会窄一点。
(mission_cam_set_position, pos2), #这个是镜头调整,将摄像机调整到主动控制运动的物体身后的某个位置,也就是你希望镜头以第一/三人称观察哪个运动对象,就以哪个运动对象的pos调,最好你们自己重调,因为我后面涉及到这些的mod改太复杂了,应用的对象五花八门不是人,所以这个参数按场景物自身体型大小来调整,一般就是y坐标往后拉,这样可以展现物体整个后部,然后Z上调一点,因为一般物体的pos在自己脚下,比如这个物体是个龙,你至少z要调脑袋高,然后为什么我上面还涉及到旋转呢,因为我这个格斗游戏启发,因为格斗游戏人物身体会侧移,然后呢,空中生物最好视角往身体下方转一下,再左侧转一下,展现生物的部分侧面模型,不然正对后背,飞起来就会感觉有一种固定视角的贴图感觉
(try_end),
]),
以上是不考虑碰撞等问题的基础场景物六向位移控制代码,下面根据不同研究对象,对于迫使基础运动状态改变(如被动运动和迫使静止)的条件,对上面代码进行分化改写:
(1),对【 (人)、 (马、坦克)】、【(鸟、直升机)、飞机】、【(鱼、潜艇)、船】、炮 基于地面碰撞和Z轴运动特性进行代码控制条件分化:
i)对于正常的人来说,不应该有Z轴的自由运动(跳跃另行分析先不考虑,可以看作持续时间较短,z轴上下单次简谐运动):
将原始基础控制代码中的:
(try_begin),
(key_is_down, key_w),
(position_move_y, pos2, 80),
(else_try),
(key_is_down, key_a),
(position_move_x, pos2, -80),
(else_try),
(key_is_down, key_s),
(position_move_y, pos2, -80),
(else_try),
(key_is_down, key_d),
(position_move_x, pos2, 80),
(else_try),
(key_is_down, key_r),
(position_move_z, pos2, 80),
(else_try),
(key_is_down, key_left_control),
(position_move_z, pos2, -80),
(try_end),
(prop_instance_animate_to_position, ":var_1", 2, 5),
改成为
(try_begin),
(key_is_down, key_w),
(position_move_y, pos2, 80),
(else_try),
(key_is_down, key_a),
(position_move_x, pos2, -80),
(else_try),
(key_is_down, key_s),
(position_move_y, pos2, -80),
(else_try),
(key_is_down, key_d),
(position_move_x, pos2, 80),
(try_end),
(position_copy_rotation, pos2, pos1), #pos1在主代码写了是玩家agent的位置,我们要知道对agent的pos来说,获取的坐标其位置始终是平行于OXY世界坐标系平面的,所以对于受重力限制z运动的拟人场景物来说,采用pos2复制一下pos1的角度。或者在我上面主体代码内把复制look pos即视角的copy rotation那句直接替换为复制agent pos的角度
(copy_position, pos10, pos2), #我们为了防止可能pos2位移控制坐标被其他判断类位移变换干扰,需要复制一个相同的pos10出来 ,也就是用于判断操作的pos和用于位移操作的pos,最好分开写。
(position_get_distance_to_ground_level, ":var_300", pos10), #获取对象场景物即将运动到的pos地面高度:var_300
(try_begin),
(ge, ":var_300", 200), #如果对象场景物在大于200的高度,即明显悬空,则强制场景物垂直方向向下位移80,模拟自由落体
(position_move_z, pos2, -80),
(else_try),
(position_move_z, pos2, 500), #因为运动延迟或地形建筑等障碍物复杂的碰撞综合条件,要把z往上抬高一点再获取射影到地面的坐标,否则有时意外到地下或者卡在其他碰撞里找ground_level的射影点会干扰位移。
(position_set_z_to_ground_level, pos2), #也就是靠近地面高度200以内即没有明显悬空时,强制位移的坐标贴合地面ground_level
try_end),
(prop_instance_animate_to_position, ":var_1", 2, 5),
也就是场景物模拟重制的“人”不应该有z轴的自由位移,要让控制自身位置变化形成位移的pos2始终保持在地面上即ground_level。
ii)对于飞机等飞行器以及鸟类等飞行生物以及修仙可以飞的人来说,可以有Z轴的自由运动,但是因为要有落地走动的行为,所以要以一个变量如slot条件来控制飞行和步行的状态切换:
首先不同飞行物的六向位移的平移旋转处理是不同的,比如修仙的人飞行可以像步行一样保持身体和面向都朝北,因为修仙的人不用遵循牛顿定律,同时左/右移动时向东/西移动而不改变身体朝向,即朝向与运动方向可以成直角,但是鸟和飞机却不是这样,由于机体构造和惯性受物理定律限制,身体朝北想东/西移动时,必须先向东/西进行旋转运动使得身体朝向东/西,再附加平移位移。再者,还有的飞行对象就是不按wasd这些基础位移按键也要运动,不然会坠毁,比如飞机和直升机的差别,直升机可以空中悬停一定的位置,你客机也行吗?空中不高速前进就等着坠下去。
不过共性的是,对于地面碰撞判断和Z轴运动状态,基本不同对象的处理模式差不多,所以不考虑朝向与运动的关系时,对于这类对象的地面碰撞判定和z轴运动控制,先将如上基础代码进行以下分化改写:
将原始基础控制代码中的:
(try_begin),
(key_is_down, key_w),
(position_move_y, pos2, 80),
(else_try),
(key_is_down, key_a),
(position_move_x, pos2, -80),
(else_try),
(key_is_down, key_s),
(position_move_y, pos2, -80),
(else_try),
(key_is_down, key_d),
(position_move_x, pos2, 80),
(else_try),
(key_is_down, key_r),
(position_move_z, pos2, 80),
(else_try),
(key_is_down, key_left_control),
(position_move_z, pos2, -80),
(try_end),
(prop_instance_animate_to_position, ":var_1", 2, 5),
改成为
(try_begin),
(key_is_down, key_w),
(position_move_y, pos2, 80),
(else_try),
(key_is_down, key_a),
(position_move_x, pos2, -80),
(else_try),
(key_is_down, key_s),
(position_move_y, pos2, -80),
(else_try),
(key_is_down, key_d),
(position_move_x, pos2, 80),
(else_try),
(key_is_down, key_r),
(troop_set_slot, "trp_player", 300, 1), #想要向上飞时自动根据slot300值自动切换到飞行模式
(position_move_z, pos2, 80),
(else_try),
(key_is_down, key_left_control),
(troop_slot_eq, "trp_player", 300, 1), #想要向下飞时自动根据slot300值必须为飞行模式才能使用,否则步行时用了下移会遁地
(position_move_z, pos2, -80),
(try_end),
(copy_position, pos10, pos2), #我们为了防止可能pos2位移控制坐标被其他判断类位移变换干扰,需要复制一个相同的pos10出来 ,也就是用于判断操作的pos和用于位移操作的pos,最好分开写。
(position_get_distance_to_ground_level, ":var_300", pos10), #获取对象场景物即将运动到的pos地面高度:var_300
(try_begin),
(troop_slot_eq, "trp_player", 300, 0), #如果slot300值切到步行模式条件的0值,那么如果对象场景物仍然在大于200的高度,则强制场景物垂直方向向下位移,模拟自由落体
(ge, ":var_300", 200),
(position_copy_rotation, pos2, pos1), #pos1在主代码写了是玩家agent的位置,我们要知道对agent的pos来说,获取的坐标其位置始终是平行于OXY世界坐标系平面的,所以对于模拟重力垂直下落的运动,采用pos2复制一下pos1的角度。
(position_move_z, pos2, -80),
(else_try),
(troop_slot_eq, "trp_player", 300, 1), #如果slot300值切到飞行模式条件的1值
(neg|ge, ":var_300", 200), #如果距离地面的高度为200,也就是飞行状态非常靠近地面时,
(neg|key_is_down, key_r), #排除在按上飞位移键R键,为什么?因为如果你结合下面靠近地面200时强制贴着地面运动自动切回步行模式,那么导致我上面写按了按R键可以自动切换飞行模式的条件变成冲突的废物条件了。
(position_copy_rotation, pos2, pos1), #pos1在主代码写了是玩家agent的位置,我们要知道对agent的pos来说,获取的坐标其位置始终是平行于OXY世界坐标系平面的,所以对于受重力限制z轴的步行运动,采用pos2复制一下pos1的角度。
(position_move_z, pos2, 500), #与前面讲的作用一样,防止碰撞条件复杂的时候,用于地面射影位置获取的pos被穿到碰撞体里面,影响判断
(position_set_z_to_ground_level, pos2), #得到对象场景物基于自身位置变换的即将到的位移位置pos2,对于地面的射影位置,然后下面控制animate运动时保证此条件下贴着地面运动。
(troop_set_slot, "trp_player", 300, 0), #使得靠地面过近但是却没有按上飞R 键的条件下,slot300值切到步行模式条件的0值
(try_end),
(prop_instance_animate_to_position, ":var_1", 2, 5),
所以说对于陆地走的和天上飞的,地面碰撞判断和Z轴运动状态的控制,也就是降落步行和飞天的状态切换控制。
iii)至于不同生物机械在前后左右移动上的的平移旋转模式差异,只需要按照我们的生活观察的常识变动一下按键或其他条件控制的六向基础位移条件:
比如对于爬行动物和鸟之类的左右移动模式可以这样调整;
将原始基础控制代码中的:
(else_try),
(key_is_down, key_a),
(position_move_x, pos2, -80),
改为
(else_try),
(key_is_down, key_a),
(position_rotate_x, pos2, -15),
(position_move_y, pos2, 40), #即按A键将边旋转15度后,边向面向的方向前进40的复合位移,也就是边转动身子边朝面向前进一点点,这种飞行运动时就比较符合鸟,飞机的左右运动模式,步行运动也符合坦克,四只脚的走兽的大部分模式(当然比如老虎不奔跑,慢慢的左右脚交叉左右移动打量猎物时,也是可以做到保持面向和运动方向为直角的情况的),也就是说,也就我们人类行为比较变态,可以保持面向朝前的情况下左右侧移。
又或者飞机的客机类,不像直升机和鸟,你就算不按WASD R ctrl,你已经飞到高空了,就不可以悬停同一个位置不动,也不可能按S键倒着飞行,就必须给一个无位移按键判断即可触发的position move y的基础位移速度,以及屏蔽S键的后退位移行为,然后WS这种前后位移按键只是为了给你的基础飞行速度加速或者减速来用。
等等类似的处理。
iV)此外对于坦克战车这种底盘特别大,不能像人一样直接垂直OXY世界坐标系平面,必须平行于实际地面坡度的,要进行地面坡度检测修正场景物实时放置的位置,一般是这么考虑的,假设按照我前面代码的写法,按照水平位移加set z to ground_level去强制修正位移坐标贴着地形,此时将底盘的大致范围表示出来,假如对于坦克,底盘范围抽象为一个长方形,那么对长方形的四个角点的坐标进行获取得到四个坐标pos,然后方便对四个pos获取与地面ground_level的高差,然后求角度,将角度根据一定运动时间进行除法,得到角运动速度,然后对整个场景物运动的pos,也就是场景物运动后设置自身位置的pos进行修正,比如你前面的地形角度为45度,那么我基础位移代码后面加上修正反向旋转(45度/一定变换时间),以一定变换角速度来修正调控。
V)然后关于水里游的,我们只需要参考陆地走的和天上飞的控制方式,因为水里游的比如像很多船只能底部一定距离贴着水面移动,这个就像人在贴着地面步行一样,只要找到水面的参考高度,参考步行运动处理即可,而对于一些鱼、美人鱼、潜泳以及潜艇来说,可以按照飞行物的飞行控制来模拟,把河床或者你人为设定的最大潜水深度对应的平面为“类比地面”,正常水面运动时浸没深度作为运动对象的“脚部”位置,然后“类比地面”以上到水面的距离类比“飞行高度范围”,然后对河岸以及其他船体礁石等障碍物进行碰撞检测判定修正运动即可。
Vi)对于大炮这种受迫运动(被人推或者被车拉)或者大部分使用的时候只需要旋转角度开火的,主要是一般这种属于多对象复合控制,也就是基本会有agent和其他prop与大炮prop的运动复合影响,所以后面与同类的运动对象一起开一个要点另行分析(或者本贴可以不写,因为这个用例是最多的)
------------------------------------------
未完待续,后面避免帖子过长,,写回复楼层里,然后对于我贴的代码实例,部分数据不一定准确,你们自身试验,因为我mod里的代码功能太集中写了,不方便从里面剥离单个功能出来,所以就在txt里随手写了下,像这个速度多少合适,镜头放在什么位置好这种xyz的取值,这个你们要根据具体的对象试验的时候反复调调,怎么顺眼怎么来。
|
评分
-
查看全部评分
|