AddActorLocalRotation()
目前我们的坦克已经可以前后移动了。在这一篇文章中,我们继续添加左右转向的功能。
之前的移动功能,是使用 AddActorLocalOffset() 函数实现的。也有类似的旋转函数,为 AddActorLocalRotation(),它的原型如下:
- void AddActorLocalRotation(FRotator DeltaRotation,
- bool bSweep=false,
- FHitResult* OutSweepHitResult=nullptr,
- ETeleportType Teleport = ETeleportType::None);
AddActorLocalRotation 的参数和 AddActorLocalOffset 也类似,只不过使用 DeltaRotation 参数指定角度。同样,bSweep 指定是否进行碰撞检测;OutSweepHitResult 指定发生碰撞时的碰撞信息;Teleport 指定旋转的移动方式。
在之前的 《AddActorLocalOffset()》 文章中,我们移动没有开启碰撞检测。现在我们需要移动和旋转都开启碰撞检测,所以来到坦克蓝图中,选择其根组件,是一个胶囊碰撞体。
如图 1 所示,我们修改细节窗体中的 碰撞 - 碰撞预设,将其修改为 BlockAllDynamic。接着我们调节一下坦克的 Mesh,让胶囊体底部不要超出,否则会碰撞到地面,导致无法控制坦克。
注意,初始摆放时,如果胶囊体碰到地面的话,就会触发碰撞,导致坦克无法移动。

设置好碰撞之后,我们开始实现左右转向功能。如代码清单 1 所示,我们定义 TurnRate 成员变量指定转向速度,并根据帧率计算旋转的角度,最终通过 AddActorLocalRotation() 设置旋转增量。
- void ATank::Turn(float Value)
- {
- FRotator DeltaRotation = FRotator::ZeroRotator;
- DeltaRotation.Yaw = Value * TurnRate * UGameplayStatics::GetWorldDeltaSeconds(this);
- AddActorLocalRotation(DeltaRotation, true);
- }
转向操作绑定的方式和移动一样,如代码清单 2 所示,使用 BindAxis() 函数设置。
- void ATank::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
- {
- Super::SetupPlayerInputComponent(PlayerInputComponent);
- PlayerInputComponent->BindAxis(TEXT("MoveForward"), this, &ATank::Move);
- PlayerInputComponent->BindAxis(TEXT("Turn"), this, &ATank::Turn);
- }
最终的效果如以下视频所示,可以看到旋转正常,碰撞也正常。