AdvancedLocomotionSystemV第八篇 C++ 实现角色翻滚和跳跃动作

Posted Tanzq-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AdvancedLocomotionSystemV第八篇 C++ 实现角色翻滚和跳跃动作相关的知识,希望对你有一定的参考价值。

所有篇章内容目录

AdvancedLocomotionSystemV

翻滚动作

演示

思维导图

状态机逻辑

AnimNotify 与 AnimNotifyState

AnimNotify 表示出来是一个点,只要动画运行到了这个位置,就会触发对应的逻辑。

跳跃动作

演示

跳跃动画演示

下落动画演示

从开始的平静到后面的抓狂,,,
(不要在意这无伤跳楼。。。)

思维导图

状态机逻辑

  • Main Movement States

  • Jump States

  • 起跳动作逻辑

    使用是左脚起跳动画,右脚也是一样的逻辑,这里就不重复说明了。

  • Jump

  • Fall

  • Land

  • Land Movement

惯性化

在过渡条件中可以看到Blend Logic,在一些过渡中,会使用惯性化来进行动画过渡。

在官方文档的那个挥手视频中,左边的是没有采用惯性化的,右边的采用了惯性化,观察左边的小白人,明明角色已经不处于挥手状态,但是它还是将挥手动作做完之后再恢复到初始状态,就看起来有点变扭。

在标准混合模式中,在过渡期间会将原姿势动画也纳入计算过程中,生成组合姿势播放出来。
而在惯性化的模式中,会截取逻辑判断已经不处于之前的状态的动画姿势与现动画进行融合,不会将原动画剩余的部分加入到其中。

落地姿势 LandPrediction 混合度的计算

生成一个预测角色是否将要落地的一个胶囊体,生成的胶囊体如下图(为了看的更加明白,我把这个检测添加到了NativeUpdateAnimation函数中,所以这个胶囊体并不是想动图所示一样一直检测。)

如果可以落地行走,根据目前将要落地的状况返回对应的落地融合度。

全部代码我就不展示了,我就展示一部分,想知道详细的代码以及解释,可以到我的Gitee项目中观看。

float UALSAnimInstance::CalculateLandPrediction()

	/ 第八次更新

	/*
	 * 通过沿速度方向追踪,找到角色下落的可行走表面,
	 * 并获得“时间”(范围为0-1,1为最大值,0为即将着陆)直至碰撞,计算着陆预测权重。
	 * 土地预测曲线用于控制时间如何影响平滑混合的最终权重。
	 */

	// 我们后面要使用GetUnsafeNormal(),只用这个去标准化向量是比较快的,但是要保证向量一定不是零向量,所以这里就做一些处理。
	if (FallSpeed >= -200.f)
	
		return 0.f;
	

	// 获取角色的胶囊体
	const auto CapsuleComp = Character->GetCapsuleComponent();

	/*
	 * 检测的起始向量就是胶囊体的位置
	 * 终止向量是以速度为方向,大小下落速度值映射为[50,2000]的向量。
	 */
	const FVector StartLocation = CapsuleComp->GetComponentLocation();
	const FVector EndLocation = StartLocation + FVector(Velocity.X, Velocity.Y,
	                                                    FMath::Clamp(Velocity.Z, -4000.f, -200.f)).
		GetUnsafeNormal() * FMath::GetMappedRangeValueClamped(FVector2D(0.f, -4000.f), FVector2D(50.f, 2000.f),
		                                                      Velocity.Z);

	/*
	 * 就是生成一个与角色运动倾斜程度相同的胶囊体,来判断角色是否已经接触到地面了。
	 */
	FHitResult OutHit;
	UKismetSystemLibrary::CapsuleTraceSingleByProfile(GetWorld(), StartLocation, EndLocation,
	                                                  CapsuleComp->GetScaledCapsuleRadius(),
	                                                  CapsuleComp->GetScaledCapsuleHalfHeight(), TEXT("ALS_Character"),
	                                                  false, , EDrawDebugTrace::ForDuration, OutHit, true);

	// 判断是否接触到了的物体,并且是可行走的。
	if (OutHit.bBlockingHit && Character->GetCharacterMovement()->IsWalkable(OutHit))
	
		/*
		 * OutHit.Time 表示的是接触位置在起始点和终止点的位置比例值。
		 * 如果在StartLocation处就已经接触了,那就是0。
		 * 如果值是在EndLocation处接触了,那就是1。
		 * 在中间接触了就按比例进行计算。
		 *
		 * 因为这个Time是由程序产生的,为了让他能够更加符合动画的融合度,所以就加入了曲线去控制他的这个值。
		 * Mask_LandPrediction 值为 0是完全使用曲线值,1的时候关闭曲线的值。
		 */
		return UKismetMathLibrary::Lerp(LandPredictionCurveFloat->GetFloatValue(OutHit.Time), 0.f,
		                                GetCurveValue(TEXT("Mask_LandPrediction")));
	

	return 0.f;
	/ 

  • CapsuleTraceSingleByProfile 根据配置进行胶囊体检测, 那么项目中的ALS_Character是在哪里配置的呢?

打开项目设置进行添加:

然后在角色配置的地方就可以看到啦!

空中倾斜量LeanInAirAmount曲线分析

以上是关于AdvancedLocomotionSystemV第八篇 C++ 实现角色翻滚和跳跃动作的主要内容,如果未能解决你的问题,请参考以下文章

AdvancedLocomotionSystemV第八篇 C++ 实现角色翻滚和跳跃动作

AdvancedLocomotionSystemV第八篇 C++ 实现角色翻滚和跳跃动作

AdvancedLocomotionSystemV第八篇 C++ 实现角色翻滚和跳跃动作

AdvancedLocomotionSystemV第七篇 C++ 实现角色蹲伏和跑步细节

AdvancedLocomotionSystemV第七篇 C++ 实现角色蹲伏和跑步细节

AdvancedLocomotionSystemV第二篇 C++ 实现镜头跟随人物缓慢移动