仅当球的角速度不太高时才在一个方向上施加扭矩

问题描述 投票:0回答:0

我正在尝试在虚幻引擎 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
的一般最大角速度。

我对最后一种方法的整个想法是检查我要施加扭矩的方向的角速度是否低于允许的最大角速度,并且仅在球旋转速度低于最大角速度时才施加扭矩在那个方向。因此,我尝试将角速度矢量标量投影到归一化方向矢量上。但是是的...

我的观念错了吗?我觉得我的数学在这个问题上不对劲!任何帮助表示赞赏。

我的目标是达到最大角速度。我可以在球的引擎中勾选物理属性“最大角速度”并输入一些值,但这也会使球的旋转速度永远不会超过我输入的最大值。但我希望有外力仍然能够通过使用控件使球旋转得比玩家旋转得更快,例如在斜坡上,球的旋转速度应该有可能超过最大值。通过玩家输入实现比最大值更快的旋转速度是不可能的。

感谢您花时间阅读我的问题!

c++ math calculus unreal-engine5 vectormath
© www.soinside.com 2019 - 2024. All rights reserved.