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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453870.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453870.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453870.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

kafka 異常:return ‘<SimpleProducer batch=%s>‘ % self.async ^ SyntaxError: invalid syntax

Python3.X 執行Python編寫的生產者和消費者報錯&#xff0c;報錯信息如下&#xff1a; Traceback (most recent call last): File "mykit_kafka_producer.py", line 9, in <module> from kafka import KafkaProducer File "/usr/local/lib/python3.7/sit…

python 分布式計算框架_漫談分布式計算框架

如果問 mapreduce 和 spark 什么關系&#xff0c;或者說有什么共同屬性&#xff0c;你可能會回答他們都是大數據處理引擎。如果問 spark 與 tensorflow 呢&#xff0c;就可能有點迷糊&#xff0c;這倆關注的領域不太一樣啊。但是再問 spark 與 MPI 呢&#xff1f;這個就更遠了。…

Codeforces 899D Shovel Sale

題目大意 給定正整數 $n$&#xff08;$2\le n\le 10^9$&#xff09;。 考慮無序整數對 $(x, y)$&#xff08;$1\le x,y\le n, x\ne y$&#xff09;。 求滿足 「$xy$ 結尾連續的 9 最多」的數對 $(x,y)$ 的個數。 例子&#xff1a; $n50$&#xff0c;$(49,50)$ 是一個滿足條件的…

Windows系統使用minGW+msys 編譯ffmpeg 0.5的全過程詳述

一.環境配置 1.下載并安裝 MinGW-5.1.4.exe (http://jaist.dl.sourceforge.net/sourcef … -5.1.4.exe)&#xff0c;安裝時選中 g, mingw make。建議安裝到c:/mingw. 2.下載并安裝 MSYS-1.0.11-rc-1.exe (http://jaist.dl.sourceforge.net/sourcef … 1-rc-1.exe)&#xff0c;安…

Liunx安裝gogs,mysql,jdk,tomcat等常用軟件

Liunx CentOS系統采用yum安裝Mysql 一.安裝mysql客戶端 yum -y install mysql 二.安裝mysql服務器端 [注意:由于CentOS7下的不自帶mysql-server,所以得先安裝資源包,步驟: 1.wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm (采用wget獲取必須有wge…

stm32單片機端口映射_STM32單片機的重映射與地址映射的使用方法及步驟

重映射STM32中對于一些端口的外設已經被其他引腳所使用&#xff0c;這是就需要用端口重映射來解決了&#xff0c;很方便。以USART1為例重映射的步驟為&#xff1a;打開重映射時鐘和USART重映射后的I/O口引腳時鐘&#xff0c;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_A…

python 第三方模塊 yaml - 處理 YAML (專門用來寫配置文件的語言)

markdown 的配置使用 Yaml —— Yet Another Markup Language &#xff1a;另一種標記語言。 簡介 YAML 是專門用來寫配置文件的語言&#xff0c;非常簡潔和強大&#xff0c;遠比 JSON 格式方便。 YAML在python語言中有PyYAML安裝包。 YAML 語言&#xff08;發音 /?jm?l/ &…

程序員 賺錢

業余編程賺錢 程序員的好方法 現在的人生活水平高了&#xff0c;開銷也大了&#xff0c;同時對于一些技術性人員來說有很多種&#xff0c;有些程序員自己開公司&#xff0c;開發自己的產品&#xff0c;年賺百萬&#xff0c;有些程序員還在給別人打工&#xff0c;每天累死累活的…

java合并單元格的快捷鍵_java poi合并單元格問題

使用poi導出的execl合并單元格&#xff0c;會出現下圖問題整個單元格看似合并了&#xff0c;但是文字沒有垂直居中&#xff0c;而且execl中所有的合并都會在第三行開始出現灰色分層樣式合并單元格偽代碼String upCompareField ""; //上一行的對比值for(int i 0; i …

webpack自動化構建腳本指令npm run dev/build

指令 為不同環境配置可執行指令&#xff0c;我們使用npm scripts方式&#xff0c;在package.json文件中配置執行指令&#xff1a; {"scripts": {"start": "cross-env NODE_ENVdev webpack-dev-server","build": "cross-env NODE_…

前端之 form 詳解

認識表單 在一個頁面上可以有多個form表單&#xff0c;但是向web服務器提交表單的時候&#xff0c;一次只可以提交一個表單。要聲明一個表單&#xff0c;只需要使用 form 標記來標明表單的開始和結束&#xff0c;若需要向服務器提交數據&#xff0c;則在form標簽中需要設置act…

代碼 優化 指南 實踐

C代碼優化方案 華中科技大學計算機學院 姓名&#xff1a; 王全明 QQ&#xff1a; 375288012 Email&#xff1a; quanming1119163.com 目錄 目錄 C代碼優化方案 1、選擇合適的算法和數據結構 2、使用盡量小的數據類型 3、減少運算的強度 &#xff08;1&…

.12-淺析webpack源碼之NodeWatchFileSystem模塊總覽

剩下一個watch模塊&#xff0c;這個模塊比較深&#xff0c;先大概過一下整體涉及內容再分部講解。 流程圖如下&#xff1a; NodeWatchFileSystem const Watchpack require("watchpack");class NodeWatchFileSystem {constructor(inputFileSystem) {this.inputFileSy…

Python 第三方模塊之 beautifulsoup(bs4)- 解析 HTML

簡單來說&#xff0c;Beautiful Soup是python的一個庫&#xff0c;最主要的功能是從網頁抓取數據。官方解釋如下&#xff1a;官網文檔 Beautiful Soup提供一些簡單的、python式的函數用來處理導航、搜索、修改分析樹等功能。 它是一個工具箱&#xff0c;通過解析文檔為用戶提供…

modal vue 關閉_Vue彈出框的優雅實踐

引言頁面引用彈出框組件是經常碰見的需求,如果強行將彈出框組件放入到頁面中,雖然功能上奏效但沒有實現組件與頁面間的解耦,非常不利于后期的維護和功能的擴展.下面舉個例子來說明一下這種做法的弊端.click"openModal()">點擊 :is_open"is_open" close…

Python 第三方模塊之 lxml - 解析 HTML 和 XML 文件

lxml是python的一個解析庫&#xff0c;支持HTML和XML的解析&#xff0c;支持XPath解析方式&#xff0c;而且解析效率非常高 XPath&#xff0c;全稱XML Path Language&#xff0c;即XML路徑語言&#xff0c;它是一門在XML文檔中查找信息的語言&#xff0c;它最初是用來搜尋XML文…

(轉)Linux下PS1、PS2、PS3、PS4使用詳解

Linux下PS1、PS2、PS3、PS4使用詳解 原文&#xff1a;http://www.linuxidc.com/Linux/2016-10/136597.htm 1、PS1——默認提示符 如下所示&#xff0c;可以通過修改Linux下的默認提示符&#xff0c;使其更加實用。在下面的例子中&#xff0c;默認的PS1的值是“\s-\v\$”,顯示出…

開放平臺大抉擇

開放平臺大抉擇之新浪SAE&#xff1a;為個人應用開發帶來福音 導讀&#xff1a;繼上期淘寶網副總裁王文彬從平臺功能特色、運營狀況等多方面分享了淘寶開放平臺的歷程和挑戰之后。國內另一家云平臺服務方的典型代表——Sina App Engine(簡稱SAE)&#xff0c;作為新浪研發中心于…

ip68級防水可以泡多久_iPhone8防水級別升級至IP68:能在1.5米深水中堅持30分鐘

1月15日&#xff0c;業界最新的泄密消息顯示&#xff0c;蘋果擬在今年推出的“iPhone 8”智能手機會是一款革命性的手機&#xff0c;功能和配置就不多說了。蘋果還將解決iPhone 7的一個重要缺陷&#xff0c;就是大大增強iPhone 8的防水性能&#xff0c;防水級別達IP68。《韓國先…

HTTP POST 發送數據的參數 application/x-www-form-urlencoded、multipart/form-data、text/plain

HTTP 簡介 HTTP/1.1 協議規定的 HTTP 請求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 這幾種。 其中 POST 一般用來向服務端提交數據&#xff0c;本文主要討論 POST 提交數據的幾種方式。 我們知道&#xff0c;HTTP 協議是以 ASCII 碼傳輸&#xff0c;建…