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,一经查实,立即删除!

相关文章

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;安…

程序员 赚钱

业余编程赚钱 程序员的好方法 现在的人生活水平高了&#xff0c;开销也大了&#xff0c;同时对于一些技术性人员来说有很多种&#xff0c;有些程序员自己开公司&#xff0c;开发自己的产品&#xff0c;年赚百万&#xff0c;有些程序员还在给别人打工&#xff0c;每天累死累活的…

代码 优化 指南 实践

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…

开放平台大抉择

开放平台大抉择之新浪SAE&#xff1a;为个人应用开发带来福音 导读&#xff1a;继上期淘宝网副总裁王文彬从平台功能特色、运营状况等多方面分享了淘宝开放平台的历程和挑战之后。国内另一家云平台服务方的典型代表——Sina App Engine(简称SAE)&#xff0c;作为新浪研发中心于…

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

vue 二进制文件的下载(解决乱码和解压报错)

问题描述&#xff1a;项目中使用的是vue框架进行开发&#xff0c;因为文件下载存在权限问题&#xff0c;所以并不能通过 a 链接的 href 属性直接赋值 URL进行下载&#xff0c; &#xff08;如果你的文件没有下载权限&#xff0c;可以直接通过href属性赋值URL的方法进行文件下载…

浅谈云计算与数据中心计算

文/林仕鼎 云计算概念发端于Google和Amazon等超大规模的互联网公司&#xff0c;随着这些公司业务的成功&#xff0c;作为其支撑技术的云计算也得到了业界的高度认可和广泛传播。时至今日&#xff0c;云计算已被普遍认为是IT产业发展的新阶段&#xff0c;从而被赋予了很多产业和…

数据挖掘:如何寻找相关项

导读&#xff1a;随着大数据时代浪潮的到来数据科学家这一新兴职业也越来越受到人们的关注。本文作者Alexandru Nedelcu就将数学挖掘算法与大数据有机的结合起来&#xff0c;并无缝的应用在面临大数据浪潮的网站之中。 数据科学家需要具备专业领域知识并研究相应的算法以分析对…

00030_ArrayList集合

1、数组可以保存多个元素&#xff0c;但在某些情况下无法确定到底要保存多少个元素&#xff0c;此时数组将不再适用&#xff0c;因为数组的长度不可变 2、JDK中提供了一系列特殊的类&#xff0c;这些类可以存储任意类型的元素&#xff0c;并且长度可变&#xff0c;统称为集合 3…

1.3tf的varible\labelencoder

1.tf的varible变量 import tensorflow as tf #定义变量--这里是计数的变量 statetf.Variable(0,namecounter) print (state.name) #输出变量值 onetf.constant(1) #常量new_valuetf.add(state,one) updatetf.assign(state,new_value)#初始化所有变量 inittf.initialize_all_var…

多线程编程指南

1. 多线程编程指南1--线程基础 线程编程指南1--线程基础 Wednesday, 29. March 2006, 11:48:45 多线程 本文出自:BBS水木清华站 作者:Mccartney (coolcat) (2002-01-29 20:25:25) multithreading可以被翻译成多线程控制。与传统的UNIX不同&#xff0c;一个传统 的UNIX进…

路由器和猫的区别

路由器和猫的区别 网络在我们现在生活中必不可少,我们链接互联网经常需要用到猫和路由器,但是依然有很多菜鸟根本不知道什么是猫什么是路由器,至于猫和路由器怎么使用就更不知道了,下面给大家详细的讲解下路由器和猫的区别。 路由器和猫的用途和链接位置不一样,如下图: 路由器:…

kafka 命令行命令大全

kafka 脚本 connect-distributed.sh connect-mirror-maker.sh connect-standalone.sh kafka-acls.sh kafka-broker-api-versions.sh kafka-configs.sh kafka-console-consumer.sh kafka-console-producer.sh kafka-consumer-groups.sh kafka-consumer-perf-test.sh kafka-dele…

python 第三方模块之 APScheduler - 定时任务

介绍 APScheduler的全称是Advanced Python Scheduler。它是一个轻量级的 Python 定时任务调度框架。APScheduler 支持三种调度任务&#xff1a;固定时间间隔&#xff0c;固定时间点&#xff08;日期&#xff09;&#xff0c;Linux 下的 Crontab 命令。同时&#xff0c;它还支持…

hadoop分布式搭建

一&#xff0c;前提&#xff1a;下载好虚拟机和安装完毕Ubuntu系统。因为我们配置的是hadoop分布式&#xff0c;所以需要两台虚拟机&#xff0c;一台主机&#xff08;master&#xff09;&#xff0c;一台从机&#xff08;slave&#xff09; 选定一台机器作为 Master 在 Master …

xvid 详解 代码分析 编译等

1. Xvid参数详解 众所周知&#xff0c;Mencoder以其极高的压缩速率和不错的画质赢得了很多朋友的认同&#xff01; 原来用Mencoder压缩Xvid的AVI都是使用Xvid编码器的默认设置&#xff0c;现在我来给大家冲冲电&#xff0c;讲解一下怎样使用Mencoder命令行高级参数制作Xvid编…

很多人喜欢露脚踝你觉得时尚吗?

当然是 时尚时尚最时尚的 露&#xff01;****脚&#xff01;脖&#xff01;子&#xff01;image.png人生就是这么奇怪 美容整形可以让你拥有想要的五官 做个手术健个身能让你拥有梦寐的线条 唯独身高这事很难改变&#xff08;说多了都是泪&#xff09; 氮素呢 再难也难不倒众位…