2025/12/31 8:44:44
网站建设
项目流程
北京网站建设方案案例,网站不备案会怎么样,网页设计图片旋转代码,jsp网站开发软件哪个好原地转身动作处理
Rotate Root Bone
在角色主要动画蓝图添加Rotate Root Bone节点#xff0c;这个节点的目的就是旋转根骨骼#xff0c;每一个角色或者说导入的动画的骨骼都会带有根骨骼#xff0c;根运动也是以该骨骼为参考点的在蓝图线程安全更新里创建一个新的函数#…原地转身动作处理Rotate Root Bone在角色主要动画蓝图添加Rotate Root Bone节点这个节点的目的就是旋转根骨骼每一个角色或者说导入的动画的骨骼都会带有根骨骼根运动也是以该骨骼为参考点的在蓝图线程安全更新里创建一个新的函数目的是动态计算角色此时的转向角度角色旋转角度如何发生通常情况下在镜头控制角色偏航的时候角色始终保持面向前方也就是角色会跟着摄像机旋转因此当摄像机旋转与角色当前朝向相差90°的时候旋转动画播放这就好像有人指着让你看向那个方位此时你就转身去看向那个方位一样。在线程安全更新的GetRotationData中我们算出了角色的上一帧的偏航角和当前帧的偏航角以及差值Delta Actor Yaw因为角色的旋转是跟着摄像机的所以实际上_这个DeltaActorYaw也能代表摄像机更新的角度_。这段算式的意思是角色骨骼旋转偏移加上角色自身旋转的角度的差并将其限制在-180度到180度这样就得到了一个类似时钟指针那样的偏移角度。然后现在我们要设定在空闲状态是否旋转创建一个枚举来区分现在调整到BlendOut会发现角色正常跟随摄像机旋转回到Idle状态机在输出姿势中绑定一个OnUpdate我们要在那里去判断和更新枚举但如果是其他状态要改变枚举的时候比较笨的方法是挨个状态机去创建并更新但我们可以设置一个序列当状态为Accumulate的时候就开启旋转随即变成BlendOut但因为Idle会强制转换成Accumulate但这样会有问题如果你已经偏移了摄像机这将导致角色实际跟踪的摄像机方向和当前的摄像机方向不一致因此我们应该在角色不处于空闲状态的一瞬间立即将角色的朝向拨正也就是先拨回和摄像机角度一致的角度。因此在下一帧把状态变成BlendOut的时候强制将其改为0运行游戏会发现Idle状态角色不会朝摄像机移动但是在Cycle和其他状态下会先拨正角色的转向然后才能保证朝摄像机移动这一过程是瞬间发生的因此我们需要一些动画来填补这个空白。使用Float Spring Interp来平滑数值我们希望其一帧一帧地改变例如10变成0分成一帧一帧地变化而不是在一帧之内瞬间变化Float Spring Interp 参数详解Current当前值作用 弹簧系统的起始位置类型 浮点数说明 这是弹簧当前的位置值每次调用时都会从这个值开始计算新的位置Target目标值作用 弹簧系统要到达的目标位置类型 浮点数说明 弹簧会向这个值移动但不会立即到达而是根据物理规律逐渐接近SpringState弹簧状态 最重要参数作用 保存弹簧的物理状态信息类型 FFloatSpringState结构体内部结构 在KismetMathLibrary.h第111-125行PrevTarget 上一个目标值Velocity 当前速度bPrevTargetValid 上一个目标是否有效关键要求 必须保存为蓝图变量 否则弹簧效果无法正常工作Stiffness弹簧刚度作用 控制弹簧的硬度默认值 无默认值必须手动设置效果 高值 如100-1000弹簧很硬快速响应几乎没有过冲低值 如1-10弹簧很软响应缓慢有明显过冲和振荡CriticalDamping临界阻尼系数作用 控制弹簧的阻尼效果默认值 无默认值必须手动设置三种状态 1.0 临界阻尼 - 最快到达目标无振荡1.0 欠阻尼 - 会产生振荡过冲和回弹1.0 过阻尼 - 缓慢到达目标无振荡DeltaTime时间增量作用 时间步长控制弹簧更新的频率推荐值 通常使用 Get World Delta Seconds 节点重要性 确保动画在不同帧率下的一致性然而在起步状态下还是会有一点偏差因此我们需要在实时获取角色转向的时候实时更新拨正角色的转向方向在停止动画和起步动画都要重新在朝向扭曲把角度差值修改成我们刚刚计算好的偏移插值运动提取修改器MotionExtractorModifiers转身动画在播放完之前如果玩家频繁地转动视角会导致转身动画不能灵活且随时地变更这里说的变更说的是旋转动画方向的变更为了解决这种情况我们需要使用运动提取修改器运动提取修改器可以允许我们提取某一个骨骼的X轴Y轴XY轴XYZ轴这样的轴的二维或三维的值这些值包括位移值旋转值Scale值等但是自动创建的曲线并不准确通常需要我们手动调整先反转曲线让其从0-90方便计算但是此时会发现这些关键帧并不准确全选曲线关键帧将Upper Bound 和 Lower Bound改为0和-90还是有些不够完美所以我们仍需要手动调整现在为每个动画都设置曲线注意提取旋转Z轴且乘以-1的值我们还需要为动画添加一个安全的曲线当我们处于转向和恢复阶段时能确保安全的曲线双击两条曲线然后调整第一帧和最后一帧的时间然后右键某一个关键帧选择自动添加平滑的曲线我们回到ABP_Layers在闲置层我们应该创建一个状态机闲置状态会进入两个状态一个转向状态一个转向后恢复状态转向后恢复状态最后会回到闲置状态Idle到TurningInPlaceEntry中当视角偏移某一个数值的时候就朝向哪边旋转播放旋转动画如果大于正数则向左转反之向右转我们在激活这个节点的绑定函数做这件事然后创建一个序列求值器复写OnUpdate在里面更新我们的动画播放判断进行动画选择判断向左还是向右超过180都会判断180所以按需播放对应角度的动画但目前还无法播放我们还需要创建一个OnUpdate事件函数从这里开始就要自行选择播放时间了Set Explicit Time节点用于 手动设置动画序列的播放时间 而不是让动画按照时间自动播放。这在以下场景中特别有用基于外部参数控制动画 - 比如根据角色跳跃高度控制跳跃动画的播放位置动画同步 - 多个角色需要同步播放同一动画的不同位置程序化动画控制 - 通过代码逻辑精确控制动画播放进度因此在这里我们需要根据上一帧到下一帧所花费的时间这个值加上我们定义好的一个值这个值是累加时间增量的用这个值去控制动画的播放时间比如一开始是0时间增量是0.2s加起来就是0.2s然后就让动画从0.2s开始播放设置完以后会发现动画只转向一次原因是我们的状态机没有恢复到Idle因此我们需要为Idle到转向以后的状态过渡到恢复转向的状态。使用GetCurveValue节点并从我们之前设置好的曲线中拿到值我们相当于用曲线关键帧上对应的值来判断了但因为计算过快的缘故导致从TuringInPlaceEentry到Recovery的过程发生得很快因此我们希望一帧计算一次将我们选择的最终动画设置为变量这里直接暴露引脚选择动画序列播放器即可所以这两个状态机实际上就是将一个动画分成了两个状态播放第一个状态主要是播放旋转动画的旋转的部分这个旋转的部分有动画内的曲线去判断然后恢复状态就是播放旋转完以后恢复的动画的部分在上面状态播放完成完成的条件由曲线判断后就到下一个状态整一个流程就是这样子。由于这两个状态都是播放同一个动画因此不需要混合然后就是进入恢复状态以后还会转身所以恢复状态可以进入转身并且条件和Idle进入转身是一样的这个设置的目的是当转身动画进入Recover以后还会检查是否超过摄像机与角色所看的角度的阈限值如果超过就继续转身然后因为二者是同一个动作所以不需要混合回到这个函数里我们之前绑定的函数这次我们创建一个新的函数在此去更新我们的偏航曲线先保存曲线的上一帧和当前帧曲线的值我们计算如果此时曲线接近0那就重置这两个帧的值反之我们就保存每一帧曲线关键帧的值然后两个值相减最后应用去更新角色实际转向因为在动画播放的时候曲线也是逐渐走的我们在Idle状态每一帧更新并应用到根运动旋转中实现转向然后是恢复状态回到Idle状态我们尝试设置自动恢复也就是状态结束以后自动触发这个规则跳到所指的状态里但有时引擎出BUG会不起作用我们需要手动设置这一点手动获取状态节点的动画并检查其播放是否结束下蹲动作处理Crouch下蹲闲置Idle动画新增一个Crouching枚举表示我们正在下蹲然后在角色Gate枚举里添加然后创建相关的输入如果当前处于下蹲则恢复为跑步如果当前是跑步和走路则变为下蹲虚幻角色类自带下蹲和不下蹲的函数主要是为了处理角色胶囊体高度变化和其他行为此外角色的运动组件也允许对胶囊体半高进行处理Can Crouch打开后在实际运行下蹲会发现摄像机变矮且胶囊体也会变为一半下蹲后角色的移动方式也是和站立相似因此我们同样需要做运动匹配步幅匹配转向扭曲等操作在线程安全更新获取角色状态的部分里我们获取角色当前的Gate然后判断是否当前处于下蹲如果当前处于下蹲则创建一个布尔变量蹲伏动画一般会分为蹲伏和取消蹲伏我们根据蹲伏状态判断来决定播放哪个动画我们需要创建上一帧和当前帧两个帧率下的布尔值变量然后通过判断其是否相等来决定播放比如上一帧没蹲这一帧蹲了那就播放蹲下如果上一帧蹲这一帧没蹲那就播放起身之后会通过状态机来实现这两个变化现在闲置动画有两种状态不止是闲置动画一种是下蹲闲置一种是正常闲置但他们都属于闲置Idle状态只是会随时切换因此我们需要回到Layer层的Idle状态机里重新判断两种状态创建一个变量来导入这样Layer分发到下面的子类就会出现这个变量就可以导入不同情况下的下蹲闲置了目前下蹲Idle没什么问题但是因为没有进入下蹲和退出下蹲的动画所以这过程是瞬间完成的看上去极不自然为了能精确调整这几个状态变化需要使用状态机原理和上面的原地转身动作类似我们需要精确地控制这些动画的播放时间Idle状态会过渡到进入蹲伏状态然后播放进入蹲伏的动画触发条件是之前定义好的蹲伏状态改变的布尔值然后在该状态创建序列播放器并禁用循环我们只希望在进入这个状态的时候改变动画为此我们需要绑定On Become Relevant函数只要蹲伏状态由A到B或是由B到A都是蹲伏状态改变所以我们还需要判断是由A到B还是由B到A来选择决定播放不同的姿势为了确保能够来回进行需要对两边施加同样的规则此外下蹲动画完成的时候也会自动恢复到Idle注意这里要区分规则的优先级自动完成播放恢复Idle优先级要比状态改变要低下蹲起步Start动画首先下蹲状态倾斜的角度应该为0.2的参数这个参数是对应BS_Lean的 然后回到Start状态的OnUpdate函数里去对Crouching状态绑定动画如法炮制因为起步动画是需要根据距离匹配来推进动画播放时间的所以我们要为这些下蹲起步动画添加曲线下蹲循环Cycle动画对于我们的下蹲循环动画一样选择曲线压缩设置在Cycle的Lyaer函数里在OnUpdate里我们为下蹲时的Cycle现在发现蹲伏的速度和我们实际设定好的速度不一致是因为角色类在进入蹲伏函数时会有自己的最大移动速度这个最大移动速度和我们所选择的不一致因此我们需要将其调整回来下蹲急停Stop动画回到StopLayer层我们想对停止层也做同样的处理把所有启动动画的根运动根锁定还有曲线压缩都设置好和上面一样如法炮制因为也会用到距离匹配因此也要打开距离曲线修改器下蹲急转Pivot动画前往Pivot层去添加下蹲时急转的动画然后依旧是如法炮制和常规状态的急转一致我们仍需要告诉什么时候急转完成了到下一个状态通过之前设置的AnimNotifyState下蹲原地转向Turn动画我们需要单独判断是否处于下蹲而设置下蹲转向动画另外和常规的下蹲一样需要设置运动提取修改器然后还是把曲线的范围规范化也就是整数化这里就不上图了和之前的转身动作处理方式一样的跳跃动画JumpFalling处理和下蹲动作一样先创建一个输入和输入上下文绑定跳跃需要两个出发点一个按下一个松开稍后会解释角色的移动组件可以规范角色跳跃时的数值跳跃高度制动减速度空气阻力等跳跃动画为了精细化操作拆分成了跳跃起步跳跃起步循环跳跃空中的过程到开始下降空中下降循环落地这些部分我们的目的是将这些动画按照我们的需求进行拼凑实现单个完整跳跃动画的自然度当然不只是跳跃在某些情况比如角色脚下的支撑突然消失此时就会自动播放下降动画然后落地的时候播放落地动画这些为了不打乱状态机我们设定一个别名我们的规则时允许目前所有状态进入跳跃状态然后我们需要两种状态我将其分为主动跳跃和被动跳跃主动跳跃就是按下跳跃的时候跳跃被动跳跃就是当我们角色不小心从空中坠落时的跳跃严格来讲也不算跳跃算坠落我们使用Conduit节点来实现Conduit节点的主要作用是 作为状态机中的条件判断节点 用于实现复杂的过渡逻辑到这个节点需要判断才能到它连接的其他节点JumpApex就是处理被动跳跃JumpStart就是处理主动跳跃不过目前我们先把_JumpSources到JumpSelector的规则设置为真然后JumpSelector也是始终为真_我们需要回到蓝图线程安全更新中去计算什么时候是主动跳跃什么时候是被动跳跃首先先判断角色是否处于空中处于空中的条件要么是正在跳跃要么是正在坠落因此我们获取角色的速度方向需要注意这里获取的角色速度方向不再是2D因为之前的2D方向只是X和Y轴的但我们这次的_速度方向是Z轴的_所以不是获取其2D了这也就是为什么我们要额外保存一个完整轴数据的角色移动速度记得同时判断是否在空中IsJumping真假反映当前是否是主动跳跃然后就是判断是否下落的部分在这两个部分分别添加对应的规则即可现在有了主动跳跃的启动状态这个状态的下一个状态就是跳跃循环状态也就是跳跃达到最高点的时候会播放的动画的状态这个状态会进入下落状态因为JumpApex也是从最高点或者不是反正是空中下落发生的在起跳动画播放完毕后自动衔接然后因为起跳只发生一次但是跳到最高点的时候不确定应不应该只发生一次因此需要循环动画也就是_前者不需要循环后者需要循环_现在我们知道起跳-起跳循环-下落那么起跳循环什么时候进入下落应该是_角色达到最高点的时候_那角色什么时候达到最高点这就需要我们手动计算我们将速度取反然后除以重力与重力缩放的积得到但我们需要在跳跃层做这些事因此回到动画接口创建跳跃层但因为这次是三个状态所以需要创建三个动画层着陆处理现在要添加着陆着陆的条件是由空中进入所以我们之前做了起跳起跳过程到达顶点现在继续添加到达顶点后应该是下落中然后是着陆现在要为下落中创建一个层回到ABP_Layer层创建JumpFallLoop层这里不再上图JumpFallLoop过程也是一直持续的所以需要点开LoopAnimation现在处理落地动画落地动画需要计算角色当前位置与地面的距离计算什么时候算是落地然后才播放JumpFallLoop也是需要一个层来播放创建的过程同样不再赘述。但是这次我们不能是简单地播放动画而是实时计算地面的距离匹配因此需要序列评估器动画配置好以后接下来就是判定规则也就是计算距离我们采用向下的球体追踪或是线性追踪本质上就是实时向下发射射线从射线碰撞若能碰撞到返回的信息与角色的当前的位置相减得到距离首先让角色的位置Z轴减去角色胶囊体的一半得到角色脚部位置起点然后终点就是角色方向Z轴减去表示方向朝下1000表示长度然后我们就可以从碰撞的对象直接能返回距离然后现在通过接口是普通接口不是动画接口传递给动画蓝图设置一个比较短的距离判定以触发它但因为我们使用序列评估器的缘故所以动画还是不会播放而我们使用序列评估器就是为了距离匹配。当激活时重写一个激活时触发的函数然后是OnUpdate函数距离匹配使用距离匹配来决定动画距离匹配的目的是根据当前的距离来决定该从哪里播放动画我们需要曲线配置因此需要为每个动画加上曲线配置有一点需要注意因为我们是下落应该是Z轴才对因此不再是XY应该改成Z这样距离匹配就应用上了然后现在落地之后也会进入状态比如Idle或者是Cycle状态因此我们还是要进入一个Conduit去判断当速度为0时回到空闲反之回到CycleCycleAlias就是CycleIdleAlias其实就是Idle我们使用别名来做到这一点速度约等于0进入Idle速度大于0进入Cycle但是因为这两个规则的优先级一样并且约等于0不一定判断得准确因此我们将进入Cycle优先级放在第一位进入Idle放在第二位然后现在是恢复动画没错着陆后还有一个恢复动画为了确保整个跳跃过程流畅自然将整个跳跃动作如此拆分然后这个动画应该作为附加动画Local Space和倾斜动画一样它可以和其他动画叠加使用例如当我们落地进入Cycle的时候把他附加到Cycle动画上会显得有缓冲自然有惯性的骨骼相对运动 Local Space附加动画基于每个骨骼的 局部坐标系 这意味着动画效果是相对于父骨骼的不会受到角色整体位置和旋转的影响。当角色移动或旋转时Local Space附加动画会保持相对稳定适合制作 表情动画、武器晃动、呼吸效果 等需要相对稳定的附加动画。当Base Pose Type选择 ABPT_AnimFrame 或 ABPT_LocalAnimFrame 时这个参数指定使用哪一帧作为基础姿态。帧索引从0开始会被自动限制在动画的有效帧范围内。然后Base Pose Animation就是当Base Pose Type选择 ABPT_AnimScaled 或 ABPT_AnimFrame 时这个参数指定使用哪个动画序列作为基础姿态的参考。比如说Additive Anim Type Local SpaceBase Pose Type ABPT_AnimFrame选择站立姿态的某一帧效果 在站立姿态基础上叠加瞄准偏移Additive Anim Type Local SpaceBase Pose Type ABPT_RefPose效果 在角色的任何动作上都叠加呼吸效果Additive Anim Type Mesh SpaceBase Pose Type ABPT_AnimScaled使用受伤前的动画作为基础效果 在原有动作基础上叠加受伤反应这样附加动画就设置好了现在有一个情况那就是在某些情况下当角色跳跃的时候是没有时间进入下坠动画的比如角色跳上一个平台然后刚好这个平台和角色能够跳跃的高度相当也就是角色刚刚好能够跳上去那么这个时候肯定是没有时间去播放下坠动画的但目前的情况就是落地动画之前一定是由下坠动画触发所以我们需要一个方法能够跳过下坠动画去进入落地动画为此创建一个状态别名表示会进入中断的状态起跳开始到达顶点开始下坠都可以进入中断这个状态会回到EndInAir状态说白了就是提前结束了跳跃的过程我们设定的规则也是如此也就是说如果起跳啊到达顶点啊开始下坠啊都突然发现不在空中了那就提前结束现在回到应用附加动画的部分先把Apply Addtive加上恢复动画需要单独的层播放因此需要新创建一个Recovery层然后在恢复动画层里再创建一个状态机并Default什么都没有默认处于的状态然后通过角色是否处于空中去判断如果不处于空中则播放FallLandRecovery状态里的动画在该动画结束以后转到默认状态为什么不直接在这个动画层直接播放动画因为当玩家连续点击空格的时候也就是连跳的时候在这种情况下播放恢复动画会导致角色在空中了还在播放的情况因此我们需要确保角色完全不处于空中才播放然后接下来我们开始算角色在空中花费了多少时间我们根据这个时间来决定角色的恢复动画开始部分比如角色下落了10秒那就从头开始播放比如角色只下落了0.5秒那就不用播放那么久也就是动态地播放角色的落地恢复动画我们处于下落状态的时候才开始累加时间当然很明显这段算式并没有正确重置下落时间为此我们回到每次跳跃或者下落都会到的状态——FallApex因为这个状态以后才开始下落也才开始计算下落时间所以到达这个状态就绑定一个函数在这个函数里面清空下落时间计算重置时间即可现在落地恢复到Idle倒是不错但是一旦落地恢复到Cycle角色的腿部就会出问题因此需要考虑在输出Alpha之前乘以一些系数比如0.6或者0.8看效果来调整同步组Sync Groups是虚幻引擎动画系统中用于 同步多个动画播放 的重要机制。它允许不同的动画节点按照相同的时间进度进行播放确保动画之间的协调性。我们开始行走这里说的是Start类型的动画当行走动画结束的时候我们希望将其_混合_到Cycle动画中本质是确保多个动画在相同的时间点播放通过领导者选举和位置同步机制实现动画的协调一致。这解决了动画不同步导致的视觉不协调问题让角色动作更加自然流畅。Sync Groups的工作原理 同步流程分组管理 将具有相同GroupName的动画节点分配到同一个同步组领导者选举 根据角色类型和混合权重选举出领导者时间同步 所有跟随者动画按照领导者的时间进度进行播放标记同步 使用动画标记Markers进行精确的帧同步为什么需要同步组避免动画不协调想象一下角色行走时如果 上半身动画 和 下半身动画 不同步脚步可能在空中时身体已经转向手臂摆动与腿部运动不匹配看起来非常不自然确保动画事件正确触发同步确保**动画通知Notifies**在正确的时间触发脚步声效果在脚接触地面时播放武器切换在动作完成时进行特效在特定动作点出现实现复杂的动画组合当需要 混合多个动画 时同步确保过渡动画平滑自然混合权重正确应用动画状态机正确切换比如场景1角色移动动画同步需求 行走、奔跑、跳跃等动画需要同步播放配置 所有移动动画使用相同的Sync Group名称效果 动画切换时保持时间连续性场景2武器攻击动画同步需求 左右手武器攻击动画需要精确同步配置 左右手动画使用相同的Sync Group角色类型为CanBeLeader效果 双手攻击动作完美同步场景3表情动画同步需求 面部表情动画需要与身体动画同步配置 表情动画作为跟随者跟随身体动画的Sync Group效果 表情与身体动作协调一致但由于混合这里说的不是同步组的混合的过程是自动处理而不是手动的因此一定程度上会出现问题比如角色的脚步混合得不好具体表现为当我们由跑步变成走路的时候由于角色的腿比如说此时是右脚收脚但因为走路的开始动画是右脚先出脚所以就导致右脚还没收完又要迈出从视觉上来看十分的不协调这一段话是以实际场景来解释上面的举例场景可以结合上面的场景食用。根据上面同步组的原理我们需要告诉虚幻引擎在所有混合的动画中比如A和BA是跑步B是走路我们需要告诉虚幻引擎哪个更重要也就是_选中其为领导者比如我们选中A是领导者而其他的动画比如B或者C或者D这些动画他们都使用领导者的同步位置确保所有动画在相同的时间点播放_。为需要同步的动画添加上这个修改器他会选择我们腿部的两个ball位置这个位置在脚上之后会自动去打上同步组标记其他动画会从它当前标记的位置开始同步当然也可以是其他的两个骨骼比如手骨反正是需要同步的地方。目前我们是脚步不同步因此需要设置为jog动画也做处理现在走路walk和短跑jog都打上了同步组标记在此处打上组名确保两个在同一个小组然后打上同步然后就是选择领导者根据自身需求选择领导者则其他动画跟随者都要去跟随领导者的同步现在我们批量处理所有的动画把行走和慢跑的删掉修改器删掉我们重新处理动画我们要为Pivot Start Stop Cycle 包括下蹲来做这里可以输入过滤帮助我们更快的找到动画序列直接添加应用即可然后现在该选择谁作为主导运行的时候当走路右脚即将收脚而跑步是先出右脚的情况下同步组修改以后跑步会变为先出左脚也就是选择了先出左脚的时间点播放看起来十分流畅自然。混合设置最后如果想为动画过渡更加流畅自然可以修改这些规则期间惯性化混合时间都可以调整一下