UE4 ShooterGame Demo的开火的代码

之前一直没搞懂按下鼠标左键开火之后,代码的逻辑是怎么走的,今天终于看懂了。但是我只是知道了代码怎么调用的,但是还没有深入看最后的开火函数的内容,我要继续研究一下ShooterWeapon.cpp里面的void AShooterWeapon::HandleFiring()方法

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 TimeBetweenShots
    const 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();
    }
}
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 server
            BurstCounter++;
        }
    }
    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 state
        if (BurstCounter > 0)
        {
            OnBurstFinished();
        }
    }

    if (MyPawn && MyPawn->IsLocallyControlled())
    {
        // local client will notify server
        if (Role < ROLE_Authority)
        {
            ServerHandleFiring();
        }

        // reload after firing last round
        if (CurrentAmmoInClip <= 0 && CanReload())
        {
            StartReload();
        }

        // setup refire timer
        bRefiring = (CurrentState == EWeaponState::Firing && WeaponConfig.TimeBetweenShots > 0.0f);
        if (bRefiring)
        {
            GetWorldTimerManager().SetTimer(TimerHandle_HandleFiring, this, &AShooterWeapon::HandleFiring, WeaponConfig.TimeBetweenShots, false);
        }
    }

    LastFireTime = GetWorld()->GetTimeSeconds();
}
时间: 2024-11-07 19:25:35

UE4 ShooterGame Demo的开火的代码的相关文章

百度地图demo中的一点代码的优化

1 @implementation RootViewController 2 3 - (void)viewDidLoad 4 { 5 [super viewDidLoad]; 6 _demoNameArray = [[NSArray alloc]initWithObjects: 7 @"基本地图功能-MapViewBaseDemo", 8 @"多地图使用功能-MultiMapViewDemo", 9 @"图层展示功能-MapViewDemo",

极客验证官方demo构建使用及代码分析

#什么是极客验证? 官方定义:极验验证是一种在计算机领域用于区分自然人和机器人的,通过简单集成的方式,为开发者提供安全.便捷的云端验证服务. #使用命令从github上获取: git clone https://github.com/GeeTeam/gt3-java-sdk.git #使用idea搭建sdk工程: >>导入已有的工程: >>选择从git克隆的项目 >>选择Project Structure 设置 >>选择工程gt3-java-sdk >

UE4 退出(关闭)程序 代码

UE4.17.2,VS2017 在要执行退出的地方加上如下语句 UKismetSystemLibrary::QuitGame(this, nullptr, EQuitPreference::Quit); 看很多例子要引入 #include "KismetSystemLibrary.h" 但我试的结果是这个include会报错,不加就好 原文地址:http://blog.51cto.com/shuxiayeshou/2300556

h5 网络断网时,返回上一个页面 demo (与检测网络代码相结合,更直观看到结果)

页面一: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>网络在线与离线</title> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maxi

[Demo]处理课表

因为一些需求,需要对课表(.xls)文件进行处理:获取课表中空课的时间并输出.如:张三周四下午第五节课没有课,就会输出"星期四下午有空".由于课表文件是.xls文件,不能使用openxlsx,遂使用xlrd,xlwt.这只是对功能的简单实现,尚存在可以优化的地方,只是暂时记录,还会更新.有个法则叫做「快速上线试错」,嗯,:) 一.xlrd 1.Install Mac/linux 将下载好的压缩包解压,cd到目录,python setup.py install 安装,可能需要sudo.

Java中的构造代码块

代码块 ----a静态代码块 ----b构造代码块 ----c普通代码块 执行顺序:(优先级从高到低.)静态代码块>mian方法>构造代码块>构造方法. a.静态代码块: 静态代码块在加载该类的时候执行,且只执行一次! 1 class Test{ 2 public static void main(String args[]) 3 { 4 Demo d1=new Demo();Demo d2=new Demo(); 5 6 } 7 } 8 9 class Demo{ 10 static{

[ 转 ]编写高质量代码:改善Java程序的151个建议

记得3年前刚到公司,同桌同事见我无事可做就借我看<编写高质量代码:改善Java程序的151个建议>这本书,当时看了几页没上心就没研究了.到上个月在公司偶然看到,于是乎又找来看看,我的天,真是非常多的干货,对于我这种静不下心的人真是帮助莫大呀. 看完整本书,也记了不少笔记,我就分享一部分个人觉得有意义的内容,也为了方便以后自己温习. --警惕自增陷阱 i++表示先赋值后自增,而++i表示先自增后赋值.下面的代码返回结果为0,因为lastAdd++有返回值,而返回值是自增前的值(在自增前变量的原始

PHP代码规范

PHP编码规范:链接,做为一个PHP程序员,在协同开发中代码规范尤为重要,下文介绍如何使用编辑器帮助我们写出符合PSR规范的代码. 本文以Sublime为开发平台,介绍PHP代码规范自动检测工具的安装步骤.各工具都有多种安装方法,以下方法是兼容Unix/Win平台的一种通用安装方法 使用到的工具: Sublime                              编辑器 Phpfmt                               代码格式化工具  (官方建议使用PHP5.5

android源码大放送(实战开发必备),免费安卓demo源码,例子大全文件详细列表

免费安卓demo源码,例子大全文件详细列表 本列表源码永久免费下载地址:http://www.jiandaima.com/blog/android-demo 卷 yunpan 的文件夹 PATH 列表 卷序列号为 0000-73EC E:. │ jiandaima.com文件列表生成.bat │ 例子大全说明.txt │ 本例子永久更新地址~.url │ 目录列表2016.03.10更新.txt │ ├─前台界面 │ ├─3D标签云卡片热门 │ │ Android TagCloudView云标签