之前一直没搞懂按下鼠标左键开火之后,代码的逻辑是怎么走的,今天看懂了之前没看懂的部分,进了一步

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的开火的代码相关推荐

  1. 京东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 ...

  2. mui组件 a 锚点定位(Demo案例演示)- 代码篇

    文章目录 `从踩坑,入坑,到跳出坑`:mui框架(在mui-scroll中如何进行页内锚点跳转) `那么,用什么方法实现锚点跳转?` `思路就是:` - 我们可以使用另外一种MUI组件,即:`(顶部选 ...

  3. kbe的UE4的demo大体解读

    写到一半发现论坛的热门帖子里官方写了个u3d的demo源码解析, 内容几乎重复, u3d跟ue4的demo框架流程几乎都是差不多的, 直接给出官方帖子的链接好了, 尴尬: http://bbs.kbe ...

  4. UE4学习-添加机关并添加代码控制

    文章目录 添加机关 代码编写 给密室添加屋顶 打印日志 控制系统角色 创建一个新游戏模式替换DefaultPawn 添加抓取组件 获取起点和终点 物体拾取,碰撞属性设置 今日完整代码 添加机关 首先向 ...

  5. swoole 异步client redis TP5 微信模板消息 demo版本比较杂 代码注释啥的都没删除 但是可以用作为参考

    tplmsg  发送模板消息的类 <?php namespace app\admin\controller; use app\admin\controller\Base; use think\C ...

  6. UE4开发常见问题:导入插件、代码调试、格式异常

    一.如何导入其他源代码插件 1.新建空插件,名字与要导入的插件相同 2.复制旧插件源代码到新插件Source目录 3.vs工程中添加旧插件的.h .cpp文件 4.修改 插件.build.cs代码,添 ...

  7. 【富文本编辑器】Ueditor的demo——创建、修改——代码使用

    文章目录 富文本编辑器 简述: 使用: 1.下载的demo: 2.项目创建: 3.修改代码: 4.使用富文本编辑器: 示例: 富文本编辑器 Ueditor的资源官网:http://fex.baidu. ...

  8. 【拉普拉斯机制代码实现demo】差分隐私代码实现系列(四)

    差分隐私代码实现系列(四) 写在前面的话 回顾 差分隐私(Differential Privacy) 拉普拉斯机制(The Laplace Mechanism) 多少噪音就足够了?(How Much ...

  9. 最新微信hook二次开发C#Demo之获取消息代码

    用[最新微信hook二次开发c#源代码]获取消息: 消息类型有以下几种 1 文本,2 图片,3 表情(gif),4 视频,5 文件,6 名片,7 位置,8 小程序,9 链接,10公众号文章列表 发送方 ...

最新文章

  1. hbuilderx简单网页代码_Python爬取网页数据
  2. svn异地同步 linux,svn库两地开发之代码数据的同步包括***连接的全套解决方案
  3. elasticsearch 报表统计_螺丝ERP销售管理系统,螺丝企业专业管理统计
  4. 投资公司的钱是自己的吗?
  5. linux6.0设置共享文件夹,[原创] how to virtualbox sharefolder共享文件夹(数据空间)设置全记录...
  6. Hibernate的HibernateUtil类补充
  7. 我的vim和emacs配置文件
  8. Centos5.8 安装 Redmine
  9. 企业微信 Android端开发
  10. linux删除用户账户_如何在Linux中删除删除用户帐户?
  11. Dynamics 365 for Phone 使用Xrm.Device.captureImage获取照片
  12. golang 浮点数操作
  13. 类里面的成员函数指针使用
  14. This probably means that Tcl wasn‘t installed properly报错
  15. oracle中的index函数,Oracle中的索引详解(整理)
  16. plugin.php,plugin.php
  17. 阿里内部的那个牛逼带闪电的Java诊断工具arthas终于开源了
  18. Exception Processing Message 0xc0000005 Parameters
  19. 2011计算机2级,2011年度计算机等级考试二级VFP基础教程(41)
  20. 怎样反汇编bzImage

热门文章

  1. 【2050 Programming Competition - 2050 一万人码 】非官方部分题解(HDU)
  2. 【OpenJudge - noi - 7624】山区建小学(dp)
  3. 【CodeForces - 1020A】New Building for SIS(模拟)
  4. python bind sock_python 在bind端口之后创建的socket如果不关闭的话会被回收吗?
  5. php中获取本月第二天,php第二天
  6. html table vtop,PART2HTML语言.doc
  7. oracle11g中的join,sql - 使用Oracle 11g中的+符号进行左外连接
  8. 二叉树相关知识及求深度的代码实现
  9. 类的6个默认成员函数:构造函数、析构函数、拷贝构造函数、重载运算符、三/五法则
  10. leetcode1502. 判断能否形成等差数列(小学生难度)