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

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐