我正在尝试在虚幻引擎 5 中实现球的移动系统。用户可以根据 3D 游戏中相机的位置向球施加扭矩,让球沿特定方向旋转。我在为球的运动实施一个好的解决方案时遇到了问题。
到目前为止,我的代码如下所示。
void ABallie::Move(const FInputActionValue &Value)
{
if (Controller != nullptr)
{
FVector2D MoveValue = Value.Get<FVector2D>();
// GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("X: %f | Y: %f"), MoveValue.X, MoveValue.Y));
FVector ForwardDirection = Camera->GetRightVector() * MoveValue.Y;
ForwardDirection.Z = 0;
FVector SideDirection = Camera->GetForwardVector() * MoveValue.X;
SideDirection.Z = 0;
FVector Direction = (ForwardDirection + SideDirection).GetSafeNormal(0.001);
Direction *= TorqueStrength;
MainBody->AddTorqueInRadians(Direction, "MainBody", true);
if (MainBody->GetPhysicsAngularVelocityInRadians().Length() > MaxRadialVelocityInRadians)
{
MainBody->AddTorqueInRadians(-Direction, "MainBody", true);
}
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, FString::Printf(TEXT("Velocity: %f"), MainBody->GetPhysicsAngularVelocityInRadians().Length()));
}
}
解释:
MoveValue
告诉我在 2D 向量中用户按下了哪些键 WASD。 X 的范围从 1 到 -1(“W”=1,“S”=-1),Y 的范围也从 1 到 -1(“A”=1,“D”=-1)。我得到相机的前向和右向矢量,并相应地乘以它以获得应该施加扭矩的前向和侧向矢量。添加并归一化前向和侧向向量以获得所需的方向向量。将方向向量与TorqueStrength
相乘得到最终的扭矩向量,它会覆盖Direction
.
关键就在这里。它工作得还不错,但如果球在另一个方向上的速度超过最大速度,它不会控制玩家在一个方向上旋转(在一个方向上达到最大速度但在另一个方向上为 0 不会让玩家旋转)另一个方向)。
MaxRadialVelocityInRadians
MaxRadialVelocityInRadians
,则通过添加扭矩矢量的负版本来“取消应用”扭矩 FVector Direction = (ForwardDirection + SideDirection).GetSafeNormal(0.001);
Direction *= TorqueStrength;
MainBody->AddTorqueInRadians(Direction, "MainBody", true);
if (MainBody->GetPhysicsAngularVelocityInRadians().Length() > MaxRadialVelocityInRadians)
{
MainBody->AddTorqueInRadians(-Direction, "MainBody", true);
}
我想以某种方式让它以更好的方式工作并想出了这个:
AngularVelocity
AngularVelocity
与Direction
的点积是否小于MaxRadialVelocityInRadians
FVector Direction = (ForwardDirection + SideDirection).GetSafeNormal(0.001);
FVector AngularVelocity = MainBody->GetPhysicsAngularVelocityInRadians();
if (FVector::DotProduct(AngularVelocity, Direction) < MaxRadialVelocityInRadians)
{
Direction *= TorqueStrength;
MainBody->AddTorqueInRadians(Direction, "MainBody", true);
}
但这失败了,因为您可以通过在向前按时左右看或在向前移动时快速点击 A 和 D 来加快速度。示例:只需按
W
向前移动即可达到 20 弧度的最高速度。然后在按住 A
的同时突然按下 W
会将旋转速度增加到 24,并在 1-2 秒后再次降低到 20。无论我尝试什么,我的第一个解决方案总是将它保持在 20,同样适用于在对象属性设置的 Max Angular Velocity
类别下设置对象 Physics
的一般最大角速度。
我对最后一种方法的整个想法是检查我要施加扭矩的方向的角速度是否低于允许的最大角速度,并且仅在球旋转速度低于最大角速度时才施加扭矩在那个方向。因此,我尝试将角速度矢量标量投影到归一化方向矢量上。但是是的...
我的观念错了吗?我觉得我的数学在这个问题上不对劲!任何帮助表示赞赏。
我的目标是达到最大角速度。我可以在球的引擎中勾选物理属性“最大角速度”并输入一些值,但这也会使球的旋转速度永远不会超过我输入的最大值。但我希望有外力仍然能够通过使用控件使球旋转得比玩家旋转得更快,例如在斜坡上,球的旋转速度应该有可能超过最大值。通过玩家输入实现比最大值更快的旋转速度是不可能的。
感谢您花时间阅读我的问题!