日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UE4 ShooterGame Demo的开火的代码

發布時間:2023/12/18 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UE4 ShooterGame Demo的开火的代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

之前一直沒搞懂按下鼠標左鍵開火之后,代碼的邏輯是怎么走的,今天看懂了之前沒看懂的部分,進了一步

ShooterCharacter.cpp

void AShooterCharacter::OnStartFire() {AShooterPlayerController* MyPC = Cast<AShooterPlayerController>(Controller);if (MyPC && MyPC->IsGameInputAllowed()){if (IsRunning()){SetRunning(false, false);}StartWeaponFire();} } void AShooterCharacter::StartWeaponFire() {if (!bWantsToFire){bWantsToFire = true;if (CurrentWeapon){CurrentWeapon->StartFire();}} }

ShooterWeapon.cpp,其中Role==ROLE_Authority表示該程序運行在服務器。如果是客戶端,則將調用ServerStartFire來調用服務端的StartFire方法。這是多人游戲中的機制

void AShooterWeapon::StartFire() {if (Role < ROLE_Authority){ServerStartFire();}if (!bWantsToFire){bWantsToFire = true;DetermineWeaponState();} }

?

void AShooterWeapon::DetermineWeaponState() {EWeaponState::Type NewState = EWeaponState::Idle;if (bIsEquipped){if( bPendingReload ){if( CanReload() == false ){NewState = CurrentState;}else{NewState = EWeaponState::Reloading;}} else if ( (bPendingReload == false ) && ( bWantsToFire == true ) && ( CanFire() == true )){NewState = EWeaponState::Firing;}}else if (bPendingEquip){NewState = EWeaponState::Equipping;}SetWeaponState(NewState); }

?

void AShooterWeapon::SetWeaponState(EWeaponState::Type NewState) {const EWeaponState::Type PrevState = CurrentState;if (PrevState == EWeaponState::Firing && NewState != EWeaponState::Firing){OnBurstFinished();}CurrentState = NewState;if (PrevState != EWeaponState::Firing && NewState == EWeaponState::Firing){OnBurstStarted();} }

?

void AShooterWeapon::OnBurstStarted() {// start firing, can be delayed to satisfy TimeBetweenShotsconst float GameTime = GetWorld()->GetTimeSeconds();if (LastFireTime > 0 && WeaponConfig.TimeBetweenShots > 0.0f &&LastFireTime + WeaponConfig.TimeBetweenShots > GameTime){GetWorldTimerManager().SetTimer(TimerHandle_HandleFiring, this, &AShooterWeapon::HandleFiring, LastFireTime + WeaponConfig.TimeBetweenShots - GameTime, false);}else{HandleFiring();} }

下面標紅的FireWeapon這個函數,實際上在AShooterWeapon中是一個虛函數,并且沒有實現,實現是放在了子類中。它有兩個子類,分別是AShooterWeapon_Instant(彈道類)和AShooterWeapon_Projectile(投擲類)

我覺得肯定真正使用到的類就是這兩個子類,所以包括之前的這個流程,實際上都是子類中的,只不過是從父類中繼承而已,當然我此時此刻沒有去深究那些方法的可見性修飾符,是否會被繼承這些細節問題,我先暫時這么認為吧

void AShooterWeapon::HandleFiring() {if ((CurrentAmmoInClip > 0 || HasInfiniteClip() || HasInfiniteAmmo()) && CanFire()){if (GetNetMode() != NM_DedicatedServer){SimulateWeaponFire();}if (MyPawn && MyPawn->IsLocallyControlled()){FireWeapon();UseAmmo();// update firing FX on remote clients if function was called on serverBurstCounter++;}}else if (CanReload()){StartReload();}else if (MyPawn && MyPawn->IsLocallyControlled()){if (GetCurrentAmmo() == 0 && !bRefiring){PlayWeaponSound(OutOfAmmoSound);AShooterPlayerController* MyPC = Cast<AShooterPlayerController>(MyPawn->Controller);AShooterHUD* MyHUD = MyPC ? Cast<AShooterHUD>(MyPC->GetHUD()) : NULL;if (MyHUD){MyHUD->NotifyOutOfAmmo();}}// stop weapon fire FX, but stay in Firing stateif (BurstCounter > 0){OnBurstFinished();}}if (MyPawn && MyPawn->IsLocallyControlled()){// local client will notify serverif (Role < ROLE_Authority){ServerHandleFiring();}// reload after firing last roundif (CurrentAmmoInClip <= 0 && CanReload()){StartReload();}// setup refire timerbRefiring = (CurrentState == EWeaponState::Firing && WeaponConfig.TimeBetweenShots > 0.0f);if (bRefiring){GetWorldTimerManager().SetTimer(TimerHandle_HandleFiring, this, &AShooterWeapon::HandleFiring, WeaponConfig.TimeBetweenShots, false);}}LastFireTime = GetWorld()->GetTimeSeconds(); }

?

void AShooterWeapon_Instant::FireWeapon() {const int32 RandomSeed = FMath::Rand();FRandomStream WeaponRandomStream(RandomSeed);const float CurrentSpread = GetCurrentSpread();const float ConeHalfAngle = FMath::DegreesToRadians(CurrentSpread * 0.5f);
   //獲取AShooterPlayerController的rotation的單位向量
const FVector AimDir = GetAdjustedAim();const FVector StartTrace = GetCameraDamageStartLocation(AimDir);const FVector ShootDir = WeaponRandomStream.VRandCone(AimDir, ConeHalfAngle, ConeHalfAngle);const FVector EndTrace = StartTrace + ShootDir * InstantConfig.WeaponRange;const FHitResult Impact = WeaponTrace(StartTrace, EndTrace);ProcessInstantHit(Impact, StartTrace, ShootDir, RandomSeed, CurrentSpread);CurrentFiringSpread = FMath::Min(InstantConfig.FiringSpreadMax, CurrentFiringSpread + InstantConfig.FiringSpreadIncrement); }

?

轉載于:https://www.cnblogs.com/heben/p/8046726.html

總結

以上是生活随笔為你收集整理的UE4 ShooterGame Demo的开火的代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。