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的开火的代码相关推荐
- 京东php asp,jd jd demo 关于php的代码里面是 一些京东的接口 包含了 重要 WEB(ASP,PHP,...) 238万源代码下载- www.pudn.com...
开发工具: PHP 文件大小: 183 KB 上传时间: 2013-04-15 下载次数: 1 详细说明:jd demo 关于php的代码里面是关于一些京东的接口里面的代码包含了一些重要-jd dem ...
- mui组件 a 锚点定位(Demo案例演示)- 代码篇
文章目录 `从踩坑,入坑,到跳出坑`:mui框架(在mui-scroll中如何进行页内锚点跳转) `那么,用什么方法实现锚点跳转?` `思路就是:` - 我们可以使用另外一种MUI组件,即:`(顶部选 ...
- kbe的UE4的demo大体解读
写到一半发现论坛的热门帖子里官方写了个u3d的demo源码解析, 内容几乎重复, u3d跟ue4的demo框架流程几乎都是差不多的, 直接给出官方帖子的链接好了, 尴尬: http://bbs.kbe ...
- UE4学习-添加机关并添加代码控制
文章目录 添加机关 代码编写 给密室添加屋顶 打印日志 控制系统角色 创建一个新游戏模式替换DefaultPawn 添加抓取组件 获取起点和终点 物体拾取,碰撞属性设置 今日完整代码 添加机关 首先向 ...
- swoole 异步client redis TP5 微信模板消息 demo版本比较杂 代码注释啥的都没删除 但是可以用作为参考
tplmsg 发送模板消息的类 <?php namespace app\admin\controller; use app\admin\controller\Base; use think\C ...
- UE4开发常见问题:导入插件、代码调试、格式异常
一.如何导入其他源代码插件 1.新建空插件,名字与要导入的插件相同 2.复制旧插件源代码到新插件Source目录 3.vs工程中添加旧插件的.h .cpp文件 4.修改 插件.build.cs代码,添 ...
- 【富文本编辑器】Ueditor的demo——创建、修改——代码使用
文章目录 富文本编辑器 简述: 使用: 1.下载的demo: 2.项目创建: 3.修改代码: 4.使用富文本编辑器: 示例: 富文本编辑器 Ueditor的资源官网:http://fex.baidu. ...
- 【拉普拉斯机制代码实现demo】差分隐私代码实现系列(四)
差分隐私代码实现系列(四) 写在前面的话 回顾 差分隐私(Differential Privacy) 拉普拉斯机制(The Laplace Mechanism) 多少噪音就足够了?(How Much ...
- 最新微信hook二次开发C#Demo之获取消息代码
用[最新微信hook二次开发c#源代码]获取消息: 消息类型有以下几种 1 文本,2 图片,3 表情(gif),4 视频,5 文件,6 名片,7 位置,8 小程序,9 链接,10公众号文章列表 发送方 ...
最新文章
- hbuilderx简单网页代码_Python爬取网页数据
- svn异地同步 linux,svn库两地开发之代码数据的同步包括***连接的全套解决方案
- elasticsearch 报表统计_螺丝ERP销售管理系统,螺丝企业专业管理统计
- 投资公司的钱是自己的吗?
- linux6.0设置共享文件夹,[原创] how to virtualbox sharefolder共享文件夹(数据空间)设置全记录...
- Hibernate的HibernateUtil类补充
- 我的vim和emacs配置文件
- Centos5.8 安装 Redmine
- 企业微信 Android端开发
- linux删除用户账户_如何在Linux中删除删除用户帐户?
- Dynamics 365 for Phone 使用Xrm.Device.captureImage获取照片
- golang 浮点数操作
- 类里面的成员函数指针使用
- This probably means that Tcl wasn‘t installed properly报错
- oracle中的index函数,Oracle中的索引详解(整理)
- plugin.php,plugin.php
- 阿里内部的那个牛逼带闪电的Java诊断工具arthas终于开源了
- Exception Processing Message 0xc0000005 Parameters
- 2011计算机2级,2011年度计算机等级考试二级VFP基础教程(41)
- 怎样反汇编bzImage
热门文章
- 【2050 Programming Competition - 2050 一万人码 】非官方部分题解(HDU)
- 【OpenJudge - noi - 7624】山区建小学(dp)
- 【CodeForces - 1020A】New Building for SIS(模拟)
- python bind sock_python 在bind端口之后创建的socket如果不关闭的话会被回收吗?
- php中获取本月第二天,php第二天
- html table vtop,PART2HTML语言.doc
- oracle11g中的join,sql - 使用Oracle 11g中的+符号进行左外连接
- 二叉树相关知识及求深度的代码实现
- 类的6个默认成员函数:构造函数、析构函数、拷贝构造函数、重载运算符、三/五法则
- leetcode1502. 判断能否形成等差数列(小学生难度)