当前位置: 首页 > ai >正文

Blaster - Multiplayer P65-PXX : 射击武器

P65_ Projectile Weapon Class

  • 这个项目设计两种武器类型,一种为发射射线检测,另一中为发射真实的 Projectile.
  • 这一节我们创建了一个武器的子类 ProjectileWeapon 用于为发射Projectile 的武器类型.
  • 创建了 Projectile 类 用于发射.

P66_ Fire Montage

  • 本节不涉及网络内容.

P67_ Fire Weapon Effects

  • 本节不涉及网络内容.

P68_Fire Effects in Multiplayer - Fire Rep

P68_1 试错 RunOnServer RPC

P68_1_1 Character FireButtonPressedInput

  • 这个方法仅在本地端控制的角色上调用.

P68_1_2 CombatComponent::FireButtonPressed

  • 简洁版代码为这个,因为这个方法仅在本地端控制的角色上调用 , 所以这两个代码等价,但是我为了逻辑的严谨性还是加上了条件判断.

P68_2 现象

P68_2_1 Server HoldWeapon Fire

  • 当Server持枪开火的时候 , 只有Server 端可以看见开火,声音和特效.
  • 按照我得理解解释一下,当Server Locally 开火的时候调用的是ServerFire(),因为Server 端不会进行RPC , 所以 只有 Server 本地端能够看见开火 , 同步不到其客户端.我们之前捡起枪的逻辑可以同步给客户端是因为 Weapon Class bReplicate = true , 他自己就同步行为了.

P68_2_2 Client HoldWeapon Fire.

  • 当 Client 持枪开火的时候 , 只有Server 端可以看见开火,声音和特效.
  • 按照我观察上面的代码啊,客户端调用的是RPC,在客户端上调用的,在服务端上执行,额确实是在服务端执行了 , 但由于RPC里面的内容不是复制的,所以我们本地的 Client Locally Control 没有开火的效果.

P68_2_3 分析

  • 温故而知新诶 , 按照我们之前装备武器的逻辑 , 如果我们想要 RunOnServer RPC 出来效果 , 那么RPC方法里面的内容需要是复制的 , 所以这里我们需要用 Multicast RPC方法.

 P68_2_4  bFireButtonPressed

  • 我们之所以不将bFireButtonPressed做成 replicated , 因为我们每次开火不会将 这个bool值改变 , 值不变 就不会发生复制行为 , 所以满足不了我们的需求.

P68_3 Multicast RPC

  • Multicast Server RPC 在 Server 上调用 , 在所有客户端执行.

P69_ The Hit Target

  • Determine The Shoot Direction.

P69_1 创建了一个基于屏幕中心确定瞄准方向的方法

void UCombatComponent::TraceUnderCrosshairs(FHitResult& TraceHitResult)
{FVector2D ViewportSize;if (GEngine && GEngine->GameViewport) {GEngine->GameViewport->GetViewportSize(ViewportSize);}FVector2D CrosshairLocation = FVector2D(ViewportSize.X/2.0f, ViewportSize.Y/2.0f);FVector CrosshairWorldPosition;FVector CrosshairWorldDirection;bool bScreenToWorld = UGameplayStatics::DeprojectScreenToWorld(UGameplayStatics::GetPlayerController(this,0),CrosshairLocation,CrosshairWorldPosition,CrosshairWorldDirection);if (bScreenToWorld) {FVector Start = CrosshairWorldPosition;FVector End = Start + CrosshairWorldDirection * TRACE_LENGTH;GetWorld()->LineTraceSingleByChannel(TraceHitResult,Start,End,ECollisionChannel::ECC_Visibility);if (!TraceHitResult.bBlockingHit) {TraceHitResult.ImpactPoint = End;}else {DrawDebugSphere(GetWorld(),TraceHitResult.ImpactPoint,12.0f,24,FColor::Red,false,         //Persistent0.0f,          //duration0,             //Depth3.0f);}}}

P69_2 在Tick中调用

void UCombatComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{Super::TickComponent(DeltaTime, TickType, ThisTickFunction);FHitResult HitResult;TraceUnderCrosshairs(HitResult);
}

P70_Spawn Projectile

  • 本节编写了开火时向前生成并发射 Projectile 的逻辑 , 并无网络内容.

P71_ Projectile Movement Component

  • 组件自己处理了 Movement Replication 非常 Nice.

P71_1 这里插播一个知识点.

  • 做抛物线不一定用样条线,我们可以设置  ProjectileMovementComponent->bRotationFollowsVelocity = true; 沿着速度方向旋转!!!.

P72_ Projectile Tracer

http://www.xdnf.cn/news/7299.html

相关文章:

  • 吉林省建筑工程专业技术人员职称评审实施办法
  • (C语言)内存分配函数
  • 计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 13.几何着色器(二)爆炸效果修改图元类型
  • BIM+GIS+loT 技术在大中型水库信息化建设中的融合应用
  • [模型优化] 1. 模型转换
  • SeleniumBase - 多合一浏览器自动化框架
  • python重庆旅游系统-旅游攻略
  • CSS 单位详解:px、rem、em、vw/vh 的区别与使用场景
  • day30-模块和库的导入
  • YOLOv8 在单片机上的几种部署方案
  • 贪心算法:多处最优服务次序、删数问题
  • 【WFAS】《Wild Face Anti-Spoofing Challenge 2023: Benchmark and Results》
  • 数据库存储空间告急?磁盘清理与归档策略全解析
  • ebpf程序入门编写
  • 使用 Flask 框架实现FTP,允许用户通过 Web 界面浏览和下载文件夹中的所有文件
  • Lombok
  • Docker 核心原理详解:Namespaces 与 Cgroups 如何实现资源隔离与限制
  • Better Faster Large Language Models via Multi-token Prediction 原理
  • Linux多进程 写时拷贝 物理地址和逻辑地址
  • 在嵌入式系统中, 一般链路层断开多久,断开TCP为好
  • GitHub排名第一的开源ERP项目:Odoo生产计划与执行的功能概述
  • 安装Anaconda后无jupyter解决方法
  • 【NLP】35. 构建高质量标注数据
  • HTTP 协议基础
  • DAY27
  • 【C语言基础语法入门】通过简单实例快速掌握C语言核心概念
  • Golang的Web应用架构设计
  • Python爬虫实战:获取国家统计网最新消费数据并分析,为从业者做参考
  • Profinet转Ethernet IP主站网关:点燃氢醌生产线的智慧之光!
  • 【技术追踪】心脏生理学知识驱动的扩散模型用于无对比剂心肌梗死增强(MICCAI-2024)