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();
}
}