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.mzph.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;建…