ue c++ 枪的子弹射向屏幕准星位置(射线检测)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值