AdvancedLocomotionSystemV第四篇 C++ 实现角色跑步旋转和原地旋转

Posted Tanzq-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AdvancedLocomotionSystemV第四篇 C++ 实现角色跑步旋转和原地旋转相关的知识,希望对你有一定的参考价值。

效果展示

查看所有文章

AdvancedLocomotionSystemV

项目地址

Gitee

项目实现思维导图


这个地方主要就是在于动画的播放和人物的旋转值进行的匹配。
通过控制动画播放的速率来控制动画播放的时间,然后角色模块收到曲线值的通知进行旋转。
动画是根运动的动画,如果不改变角色移动的旋转值,那么角色就会在原朝向播放动画。

Rotation Amout曲线的实现

创建蓝图,继承Animation Modifier类,里面有两个函数可以进行重载。
一个是On Apply函数,主要作用是用来应用,对动画序列做出一些修改。
另一个是On Revert函数, 进行恢复的操作,恢复对动画序列做出的修改。
可以理解为Do和Undo的作用。

在生成旋转值曲线的时候,我们只需要生成动画曲线,没有其他的改变,所以只要重载On Apply函数即可。

函数实现逻辑很简单。

  1. 检查在生成这个曲线之前有没有该曲线,如果有,进行删除。
  2. 生成新曲线,此时曲线就是一个值为0的直线。
  3. 循环遍历每一帧,计算实际当前帧的旋转值与下一帧的旋转值的差值并添加到曲线中。
  4. 对动画序列进行应用。

具体实现可以在下面的文件夹中找到。

打开旋转的动画,进行生成曲线操作。


如何实现任意角度旋转?

如果使用的是同一个动画,不管旋转多少度,他们所花费的时间是一样的。
也就是说旋转的任意角度只会影响到角色旋转。

  • 计算出旋转值的缩放量,因为动画时间是一样的,所以需要对曲线的值进行调整,旋转的角度和动画播放的角度会形成一个比例,那么近似的来看,实际曲线的取值和动画播放的取值也会形成一个比例:
// 步骤4: 计算旋转的缩放量 缩放量无单位,只是旋转值的倍数关系。
if (TargetTurnAsset.bScaleTurnAngle)

	// 旋转值的缩放量  = 要旋转的角度 ÷ 动画播放的角度 × 旋转速率 × 动画播放速率缩放值
	//                   =          角度比例 × 旋转速率 × 动画播放速率缩放值
	RotationScale = TurnAngle / TargetTurnAsset.AnimatedAngle * TargetTurnAsset.PlayRate * PlayRateScale;

else

	// UE_LOG(LogTemp, Warning, TEXT("开启"));
	// 因为这个状态没有开启任意角度旋转,而是使用动画原本的角度,所以角度比例就是 1
	// 所以 旋转的缩放量  = 旋转速率 × 动画播放速率缩放值
	RotationScale = TargetTurnAsset.PlayRate * PlayRateScale;

  • 通过状态机更改曲线的方式对曲线进行缩放处理

  • 角色监听曲线的变化,一旦曲线有值并且可以使用动画过渡,就对角色进行旋转处理。
// RotationAmount曲线中取出来的值CurrentSecondRotation代表的是当前时间(s)的旋转旋转差值。 
// 可理解为 旋转度每秒
const float CurrentSecondRotation = GetAnimCurveValue(TEXT("RotationAmount"));
if (FMath::Abs(CurrentSecondRotation) > 0.001)

	/*
	 * AddActorWorldRotation 就是在原基础上添加一个Rotation的值,
	 * 这个添加是一次性的,也没有过渡的过程,一步到位。
	 * 如果没有乘倍数,旋转的值会很大,为什么?
	 * 因为没有乘以倍数的话,那么添加的值就会等于  1 s * CurrentSecondRotation。
	 * 实际上 GetWorld()->DeltaTimeSeconds是比1s小很多的,
	 * 再加上浮点计算有精度丢失的情况,那么就会导致最终累加起来的值和我们想要的值相差很大,
	 * 所以需要乘以一个值来减少他的误差。
	 */
	AddActorWorldRotation(FRotator(0.f, GetWorld()->DeltaTimeSeconds * 30.f
	 * CurrentSecondRotation, 0.f));
	TargetRotation = GetActorRotation();

以上是关于AdvancedLocomotionSystemV第四篇 C++ 实现角色跑步旋转和原地旋转的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

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

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