void AShooterCharacter::FireWeapon()
{
if (FireSound)
{
UGameplayStatics::PlaySound2D(this,FireSound);
}
const USkeletalMeshSocket* BarrelSocket = GetMesh()->GetSocketByName("BarrelSocket");
if (BarrelSocket)
{
const FTransform SocketTransform = BarrelSocket->GetSocketTransform(GetMesh());
if (MuzzleFlash)
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(),MuzzleFlash,SocketTransform);
}
FVector BeamEnd;
//在这里创建bBeamEnd变量,即调用了一次GetBeamEndLocation函数
bool bBeamEnd = GetBeamEndLocation(SocketTransform.GetLocation(),BeamEnd);
if (bBeamEnd)
{
if (ImpactParticles)
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactParticles, BeamEnd);
}
UParticleSystemComponent* Beam = UGameplayStatics::SpawnEmitterAtLocation(GetWorld(),BeamParticles,SocketTransform);
if (Beam)
{
Beam->SetVectorParameter(FName("Targert"), BeamEnd);
}
}
}
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
if (AnimInstance && HipFireMontage)
{
AnimInstance->Montage_Play(HipFireMontage);
AnimInstance->Montage_JumpToSection(FName("StartFire"));
}
}
bool AShooterCharacter::GetBeamEndLocation(const FVector& MuzzleSocketLocation, FVector& OutBeamLocation) {
//获取屏幕大小
FVector2D ViewportSize;
if (GEngine && GEngine->GameViewport)
{
GEngine->GameViewport->GetViewportSize(ViewportSize);
}
//用变量CrosshairLocation获取准星在屏幕的位置
FVector2D CrosshairLocation(ViewportSize.X / 2.f, ViewportSize.Y / 2.f);
CrosshairLocation.Y -= 50.F;
FVector CrosshairWorldPosition;
FVector CrosshairWorldDirection;
//调用DeprojectScreenToWorld方法来获取准星所在的 世界 位置和方向
bool bScreenToWorld = UGameplayStatics::DeprojectScreenToWorld(UGameplayStatics::GetPlayerController(this, 0), CrosshairLocation, CrosshairWorldPosition, CrosshairWorldDirection);
if (bScreenToWorld)
{
FHitResult ScreenTraceHit;
const FVector Start{ CrosshairWorldPosition };
const FVector End{ CrosshairWorldPosition + CrosshairWorldDirection * 50'000.f };
OutBeamLocation = End;
GetWorld()->LineTraceSingleByChannel(ScreenTraceHit, Start, End, ECollisionChannel::ECC_Visibility);
//上面进行第一次射线检测,判断枪口到准星的位置生成的射线是否有 被阻挡
if (ScreenTraceHit.bBlockingHit)
{
OutBeamLocation = ScreenTraceHit.Location;
}
FHitResult WeaponTraceHit;
const FVector WeaponTraceStart{ MuzzleSocketLocation };
const FVector WeaponTraceEnd{ OutBeamLocation };
GetWorld()->LineTraceSingleByChannel(WeaponTraceHit, WeaponTraceStart, WeaponTraceEnd, ECollisionChannel::ECC_Visibility);
if (WeaponTraceHit.bBlockingHit)
{
OutBeamLocation = WeaponTraceHit.Location;
}
UE_LOG(LogTemp, Warning, TEXT("Fire Weapon"));
return true;
}
return false;
}