GASP笔记01

我也是才开始看GASP项目,对里面的东西理解可能会不到位

角色蓝图

移动基础

先来看角色wasd移动是怎么实现的:增强输入中获取输入的X和Y的浮点值作为角色方向的平面XY轴的值,然后只取Pawn的左右和前后的偏航旋转来计算出角色的角度,比如如果此时X和Y轴都是1那么计算出45°方向,如果X轴是1/-1,Y轴是0那么就是向左/右

疾跑和下蹲也是一样的驱动方式,这里用了一个结构体变量,里面塞了两个布尔值表示当前处于疾跑还是下蹲状态,根据状态的变化来判定是否是疾跑下蹲,这个变量是复制 的,而更新的函数是仅服务器驱动的。

角色步态-移动数据计算

角色的移动数据计算,包括速度,加速度这些数值,在每帧处理,GASP自定义了一套Tick机制,叫Pre CMC Tick,这个Tick发生在自带的Tick之前,PreCMC构建在组件之中,这个组件是ActorComponent,因此PreCMCTick是TickComponent

在这个事件里会调用第一个更新函数:更新角色的旋转相关,它首先会判断角色当前是否处于瞄准状态,以此来确定角色是否需要跟随镜头旋转而旋转,然后判断角色是否处于下落状态,以此来更新角色在yaw角度的旋转速率

实际测试时,按下右键(瞄准)然后移动鼠标,会发现角色会跟随镜头转身,反之不会,然后空格(跳跃)时,移动鼠标旋转视角会发现角色会在下落的时候旋转至对应方向,这是该函数的所有工作。

另一个函数是负责计算角色的加速度,移动速度,摩擦力,地面摩擦力,制动速度,最大行走速度,最大蹲伏速度,以及计算决定角色此时的移动状态(是跑还是疾跑还是走路,以下简称"步态")

下面的就不说了点开这些pure函数可以看到是怎么计算的,它们最终都会更新到角色的移动组件上对应的变量,我们主要看上面的Gait

Gait是角色的步态,可以看到这个函数最终会返回一个枚举,GetDisiredGait主要是获取角色一个"想要移动的状态",它通过判断角色的按键值来精细控制角色当前是想要移动还是想要疾跑,这个函数会影响到后续的运动匹配!

首先,它会根据输入的XY轴的值来与一个硬编码的值(默认为0.7,目前没看到哪里有动态修改它,它目前是写死的)进行对比,如果大于它则判定为**"完全按下"(Full Movement Input),如果此时是可以疾跑状态**则最终输出疾跑,如果不可以疾跑但已经完全按下则最后输出短跑,如果不可以疾跑但处于想要走路状态但因为此时已经完全按下则最后输出为短跑,如果处于想要走路且尚未完全按下则最后输出为走。

这个完全按下我实测下来,键鼠的话Get IA_Move输出的浮点数只有0-1,也就是说中间不会有过渡的变化,所以这一段应该是用来处理手柄的,因为手柄推动摇杆的值不是0和1,这也就是为什么轻推摇杆角色会走

跳跃-翻越计算

跳跃这里会通过一个函数(以下称"尝试攀爬/翻越函数")判断是否有障碍物来决定是跳一下还是攀爬/翻越。

尝试攀爬/翻越函数分步骤进行,第一步先获取角色当前的位置,胶囊体大小和半高两个浮点数,和绘制调试数据的数值

第二步是接收一个结构体中的数据,这个结构体的计算在Get Traversal Check Inputs也就是在尝试翻越函数调用的时候通过这个函数输入

这个函数是从角色的移动组件中获取角色当前的移动状态枚举,比如游泳,下落,飞行,步行,然后计算角色的反向旋转(从旋转后的坐标系转换成原始坐标系的向量,以此获得距离值),最后返回角色的向前方向向量,向前方向向量的距离(长度),原始偏移和终点偏移,胶囊体的半径和半高,这个函数是为了判断角色不同移动状态下计算攀爬/翻越所需要的预测胶囊体型追踪的所需计算值,最终结果是,例如处于下落状态(跳跃的时候也算falling)下,这个胶囊体型追踪会稍微往前,往上一点,目的是角色如果前面有一个比他高的墙,如果这个追踪命中到了判定点,那么此时就会做攀爬/翻越相关的逻辑

回到尝试攀爬/翻越函数,在第二步就做了这么一个计算

命中以后尝试转换对应类型的对象,如果无法转换则此次攀爬/翻越失败,说明攀爬/翻越是要特定类型的Actor的,就是场景中那些可攀爬/翻越的对象

这个Actor身上附着四个样条线,这个样条线是用来做角色攀爬时手吸附的位置

在GetLedgeTransforms中,也是分为两步进行

第一步是先寻找距离角色最近的样条线,它最终会返回这个样条线的对象

这个函数内部会不断筛选样条线并比较它们之间的距离直到获取最小距离,并在便利结束以后返回该样条线对象,以此这个函数是在获取距离角色最近的样条线和它的距离。

回到GetLedgeTransforms函数,在得到样条线以后,判断角色发出的胶囊体型追踪命中的点和该样条线的距离,然后通过计算算出角色开始攀爬的点并储存在结构体中

然后还有一种情况,如果墙体比较薄的话人物会直接翻越过去,翻越的话需要当前攀爬/翻越的样条线的****++对面++ **的样条线,而这个情况写成了键值对,也就是map,在该actor的构造脚本**中定义了

获取到对面的样条线以后,我们就根据当前攀爬/翻越的点到这个样条线最近的点来作为翻越的终点,这两个点之间的线段一定是保证最短的,即确保角色在翻越开始到翻越角色不会出现偏移的情况

现在再回到尝试攀爬/翻越函数,我们看第三步,第三步主要是检测攀爬/翻越的上方是否有足够的空间,如果空间不够则之间返回false表示当前不允许翻越,然后再检测翻越的整个过程是否有对象阻挡,最后一步(step3.6)会检测在翻越以后是平地还是有高低差的平地,比如角色翻过去了但后边是悬崖

翻越前面是否有障碍物或者是不够胶囊体高度的障碍物情况

翻越前面高度检测的情况,这个检测会用于后面的下落动画选择

第三步所检测的所有数据都会存放到Traversal Check Result的结构体里,然后接着看第五步(step 5.3),这一步是根据上面计算得到的结构体中的数据,去选择动画蒙太奇进行播放,这个选择放到一个选择器里,它除了接受Traversal Check Result的结构体里保存的数据,还额外接受角色的地面移动速度,步态(Gait),以及角色的运动模式(游泳飞行那些)

在这个选择器里,我们可以看到,它会根据输入的数据情况,来选择输出不同的枚举结果,除此之外,它还返回一个结果,这个结果就是动画蒙太奇序列,比如obstacleDepth,就是翻越时需要检测前方是否有障碍物的长度区间,BackLedgeHeight就是翻越后距离地面高度的检测区间,59到无限高选它,不超过10选它等,最终经过选择后都会转化四个枚举。

点进内部还会选择,如果测试的时候会发现,角色奔跑翻越和贴着墙攀爬/翻越,姿势不一样,角色行走攀爬/翻越,高度区间的攀爬/翻越也不一样

然后回到攀爬/翻越函数,来看step5.4,在获得动画序列以后,获取角色当前主要用到的动画蓝图,然后手动调用运动匹配,让运动匹配去从中选择动画,例如当前跑步的时候是左脚在前那么起跳的时候就会选择一个相近的动画进行匹配也就是左脚在前的起跳。

然后返回的结果存到Traversal Check Result中,接着到step5.5

在5.5步中就开始播放蒙太奇了,首先会进入到Perform Traversal Action,先调用update warp Targets,这个函数主要用到一个叫motion wrap插件的技术,这个插件主要是一种可以动态调整角色的根骨骼运动以对齐目标的功能,比如我们的攀爬,每次攀爬高墙的高度都不一样,这个关于高度的数据肯定不是写死的,是会动态改变的,同样的这个插件也可以用于做近战吸附和处决动画。

这个函数需要一个Fname来作为时机,也就是只有动画播放到这个FName的时候,才会有效果,这个FName在蒙太奇里就是AnimState。

相关推荐
岁月的眸2 小时前
短期投资笔记
笔记
做cv的小昊2 小时前
3DGS加速&压缩指标评测方法、高斯数量变化曲线绘制——Training Time、FPS、Gaussian Number、Peak Memory
笔记·计算机视觉·3d·开源·github·图形渲染·3dgs
暴风游侠2 小时前
金融经济学笔记
笔记·金融
Yu_Lijing3 小时前
基于C++的《Head First设计模式》笔记——模版方法模式
笔记·设计模式
安小牛3 小时前
Apache License 2.0的中文介绍及其许可使用
笔记·apache
孟无岐3 小时前
【Laya】Animator2D 使用指南
typescript·游戏引擎·游戏程序·laya
航Hang*3 小时前
Photoshop 图形与图像处理技术——第9章:实践训练4——图层和蒙版
图像处理·笔记·ui·photoshop·期末·复习
摇滚侠3 小时前
尚硅谷 Java 零基础全套视频教程,System、Runtime、BigDecimal、BigInteger、Random,笔记 151
java·开发语言·笔记
hetao17338373 小时前
2026-01-14~15 hetao1733837 的刷题笔记
c++·笔记·算法