C++ Projectile Motion Help (Пуля не появляется при наведении вниз, после выхода за определенный угол)

Я столкнулся с проблемой в моей нереальной игре движка. По сути, моя пуля перестает появляться после определенного угла, из-за того, что z-составляющая значений скорости становится отрицательной, и, таким образом, я не могу на самом деле стрелять в землю после определенного угла. Может кто-нибудь сказать мне, если мой код правильный, я думал, что это было, пока я не обнаружил эту проблему. По сути, когда я начал отлаживать компоненты скорости, я обнаружил, что получаю отрицательные значения для Z-компонента траектории, поэтому пуля никогда не появляется.

Весь код движения снаряда:

    //Projectile motion prerequisites
    PrimaryActorTick.bCanEverTick                       = true;
    ProjectileSpeed                                     = 80000.00000f;
    a                                                   = -980.665f;
}

void AFPSProjectile::BeginPlay()
{
    Super::BeginPlay();

    ProjectileMovement->InitialSpeed    = ProjectileSpeed;
    shotCoordinate                      = GetActorLocation();
    calculateVelocity();

    calculateAirDuration();
    InitialLifeSpan                     = t;

    FTimerHandle DummyHandle;
}

void AFPSProjectile::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    currentT += DeltaTime;
    updateTrajectory();
}

//v.x = cos(θ) * v (For the x, y and z velocity components of the true trajectory of the projectile)
void AFPSProjectile::calculateVelocity()
{
    AFPSCharacter *myPlayer             = Cast<AFPSCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
    float horizontalPlayerAngle         = myPlayer->GetFirstPersonCameraComponent()->GetComponentRotation().Yaw;
    float verticalPlayerAngle           = myPlayer->GetFirstPersonCameraComponent()->GetComponentRotation().Pitch;
    float initialHorizV                 = FMath::Cos(FMath::DegreesToRadians(verticalPlayerAngle)) * ProjectileSpeed;

    u.xVelocity                         = FMath::Cos(FMath::DegreesToRadians(horizontalPlayerAngle)) * initialHorizV;
    u.yVelocity                         = FMath::Sin(FMath::DegreesToRadians(horizontalPlayerAngle)) * initialHorizV;
    u.zVelocity                         = FMath::Sin(FMath::DegreesToRadians(verticalPlayerAngle)) * ProjectileSpeed;
    ProjectileMovement->Velocity.X      = u.xVelocity;
    ProjectileMovement->Velocity.Y      = u.yVelocity;
    ProjectileMovement->Velocity.Z      = u.zVelocity;

    //Debugging the velocity components
    if (GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, FString::Printf(TEXT("xVelocity: %f"), u.xVelocity));
        GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, FString::Printf(TEXT("yVelocity: %f"), u.yVelocity));
        GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, FString::Printf(TEXT("zVelocity: %f"), u.zVelocity));
    }
}

//t = -2v / a (v = u + at) (Double the time taken for the projectile to reach the maximum height)
void AFPSProjectile::calculateAirDuration()
{
    t = ((2 * u.zVelocity) * -1) / a;

    //Debugging the air duration
    if (GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, FString::Printf(TEXT("Air Duration: %f"), t));
    }
}

//v = u + at (For velocity at the current time interval)
void AFPSProjectile::updateTrajectory()
{
    v                                   = u.zVelocity + (a * currentT);
    ProjectileMovement->Velocity.Z      = v;

    //Debugging the velocity
    if (GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, FString::Printf(TEXT("Velocity: %f"), v));
    }
}

void AFPSProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
    // Only add impulse and destroy projectile if we hit a physics
    if ((OtherActor != NULL) && (OtherActor != this) && (OtherComp != NULL))
    {
        if (OtherComp->IsSimulatingPhysics())
        {
            OtherComp->AddImpulseAtLocation(GetVelocity() / 8.0f, GetActorLocation());
        }

        Destroy();
    }
}

0 ответов

Другие вопросы по тегам