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

Unity之PUN实现多人联机射击游戏的优化(Section 3)

目录

💣一、准备工作

💣二、生成弹头脚本的编写

💣三、实现发射和伤害同步 


手雷都加了在给狗剩加个火箭筒不过分吧。效果看GIF动图,分别是单机和联机的效果。

添加火箭筒依旧是在原有的基础上更改,我查看火箭筒模型的时候资源里把关于弹头爆炸的脚本也都实现好了。实现了手雷的同步功能后再去写火箭筒就感觉简单多了。


 一、准备工作

先在素材中找到火箭筒模型,名字是 Rocket_Launcher_01

弹头的模型,名称是 Rocket_Launcher_01_Projectile 。把碰撞组件和刚体组件加好,并且把弹头和爆炸特效的标签设置为 “Boom”,用来做伤害检测,和手雷的伤害检测共用一套逻辑。

把火箭筒装到玩家 Player 模型上,我们通过武器组件的激活来实现武器切换的效果。

这里是单个武器组件的切换,如果武器多的话就把所有武器放进一个数组里,通过数组下标进行切换。

二、生成弹头脚本的编写

我把前边的手雷脚本单独拎出来了,handGrenade,然后把手持类武器放进了同一个脚本中用于归类。

public class handGrenade : MonoBehaviour
{//手雷public GameObject handGrenadePrefab;//手雷生成点public Transform handGrenadeTf;void Start(){}public void AttGrenade(){//实例化一个手雷GameObject handGrenadeObj = Instantiate(handGrenadePrefab,handGrenadeTf.transform.position,handGrenadeTf.transform.rotation);handGrenadeObj.GetComponent<Rigidbody>().AddForce(transform.forward * 1,ForceMode.Impulse);  //投掷速度   让中心点跟枪口位置可自行调整摄像机的偏移值}

Gun 脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;//枪的脚本
public class Gun : MonoBehaviour
{public int BulletCount = 15;public GameObject bulletPrefab;public GameObject casingPreafab;public Transform bulletTf;public Transform casingTf;//火箭筒弹药数量public int RocketBulletCount = 1;//弹头预设体public GameObject rocketBulletPrefab;//火箭筒发射点public Transform RocketBulletTf;void Start(){}public void Attack(){//实例化一个子弹GameObject bulletObj = Instantiate(bulletPrefab);bulletObj.transform.position = bulletTf.transform.position;bulletObj.GetComponent<Rigidbody>().AddForce(transform.forward * 500, ForceMode.Impulse);  //子弹速度   让中心点跟枪口位置可自行调整摄像机的偏移值GameObject casingObj = Instantiate(casingPreafab);casingObj.transform.position = casingTf.transform.position;}public void RocketAttack(){//实例化一个火箭筒弹头GameObject bulletObj = Instantiate(rocketBulletPrefab);bulletObj.transform.position = RocketBulletTf.transform.position;bulletObj.GetComponent<Rigidbody>().AddForce(transform.forward * 300, ForceMode.Impulse);  //子弹速度   让中心点跟枪口位置可自行调整摄像机的偏移值}}

三、实现发射和伤害同步 

PlayerController 脚本中我们要做的事:

  • 实现武器的切换
  • 生成弹头的同步
  • 实现伤害同步 
  • 换弹药的逻辑(枪换弹药和火箭筒换弹药)

换枪的动画暂时就先用换弹的动画代替了。


下面代码有些和之前是重复的,不过火箭筒都用到这些的 

伤害、得分和爆炸范围(爆炸范围是修改爆炸特效的半径)大家可以自己调整,我这里火箭筒和手雷的伤害检测得分共用同一个逻辑 —— 都是爆炸伤害。

//角色控制器 
public class PlayerController : MonoBehaviourPun,IPunObservable
{public Gun gun; //枪的脚本public handGrenade HandGrenade; //手雷的脚本//装载火箭筒、枪的预设体public GameObject RocketObject;public GameObject GunObject;//目标变量用来切换武器,1为枪  0为火箭筒int RocketFlag = 1;void Start(){gun = GetComponentInChildren<Gun>();HandGrenade = GetComponentInChildren<handGrenade>();}void Update(){//Debug.Log(photonView.Owner.NickName);//判断是否是本机玩家  只能操作本机角色if (photonView.IsMine){if (isDie == true){return;}UpdatePosition();UpdateRotation();InputCtl();}else{UpdateLogic();}}//角色操作public void InputCtl(){switch (RocketFlag){case 0://火箭筒if (Input.GetMouseButtonDown(0)){//判断子弹个数if (gun.RocketBulletCount > 0){//如果正在播放填充子弹的动作不能开枪if (ani.GetCurrentAnimatorStateInfo(1).IsName("Reload")){return;}RocketShell.SetActive(false);gun.RocketBulletCount--;Game.uiManager.GetUI<FightUI>("FightUI").UpdateBulletCount(gun.RocketBulletCount);//播放开火动画ani.Play("Fire", 1, 0);StopAllCoroutines();StartCoroutine(RocketAttack());}}//火箭筒if (Input.GetKeyDown(KeyCode.R)){//填充子弹AudioSource.PlayClipAtPoint(reloadClip, transform.position); //播放填充子弹的声音ani.Play("Reload");RocketShell.SetActive(true);gun.RocketBulletCount = 1;Game.uiManager.GetUI<FightUI>("FightUI").UpdateBulletCount(gun.RocketBulletCount);}break;case 1:if (Input.GetMouseButtonDown(0)){//判断子弹个数if (gun.BulletCount > 0){//如果正在播放填充子弹的动作不能开枪if (ani.GetCurrentAnimatorStateInfo(1).IsName("Reload")){return;}gun.BulletCount--;Game.uiManager.GetUI<FightUI>("FightUI").UpdateBulletCount(gun.BulletCount);//播放开火动画ani.Play("Fire", 1, 0);StopAllCoroutines();StartCoroutine(AttackCo());}}if (Input.GetKeyDown(KeyCode.R)){//填充子弹AudioSource.PlayClipAtPoint(reloadClip, transform.position); //播放填充子弹的声音ani.Play("Reload");gun.BulletCount = 15;Game.uiManager.GetUI<FightUI>("FightUI").UpdateBulletCount(gun.BulletCount);}break;default:Debug.Log("------------error");break;}//按ESC退出游戏// if (Input.GetKeyDown(KeyCode.Escape))// {//     Application.Quit();// }//持续按下按键,查看计分板if (Input.GetKey(KeyCode.Tab)){Game.uiManager.ShowUI<ScoreboardUI>("ScoreboardUI");Game.uiManager.ShowUI<ScoreboardUI>("ScoreboardUI").UpDateScore();}else if(Input.GetKeyUp(KeyCode.Tab)){Game.uiManager.CloseUI("ScoreboardUI");}if (Input.GetKeyDown(KeyCode.Q)){if (boolHandGrenade == false){boolHandGrenade = true;//每隔5秒才可以扔一次Invoke("boolThrowHandGrenade", 5f);//播放投掷手雷动作动画ani.Play("Grenade_Throw");StopAllCoroutines();StartCoroutine(AttHandGrenade());}}//按E切换枪和火箭筒if (Input.GetKeyDown(KeyCode.E)){ani.Play("Reload");if (RocketFlag == 1){RocketObject.SetActive(true);GunObject.SetActive(false);Game.uiManager.GetUI<FightUI>("FightUI").UpdateBulletCount(gun.RocketBulletCount);RocketFlag = 0;}else{RocketObject.SetActive(false);GunObject.SetActive(true);Game.uiManager.GetUI<FightUI>("FightUI").UpdateBulletCount(gun.BulletCount);RocketFlag = 1;}}}//火箭筒攻击协程IEnumerator RocketAttack(){//延迟0.1秒才发射子弹yield return new WaitForSeconds(0.1f);//播放射击音效AudioSource.PlayClipAtPoint(shootClip, transform.position);photonView.RPC("AttackRocketRpc", RpcTarget.All);  //所有玩家执行 AttackRpc 函数}//执行火箭筒同步[PunRPC]public void AttackRocketRpc(){gun.RocketAttack();}//监听发生碰撞: 只监听发生碰撞的一瞬间 —— 火箭筒和手雷共用private void OnCollisionEnter(Collision collision)  //参数 collision 就是你碰撞到的物体的碰撞信息{//给地面一个图层"Ground"   collision.collider.tag == "Ground"   可以判断物体是否踩在地面上if (collision.collider.tag == "Boom"){GetHit(localPlayer,3,2);}}//同步所有角色受伤: p 本机玩家,addScore 获得的分, AttackHp 不同武器的伤害值不同public void GetHit(Player p,int addScore,int AttackHp){if (isDie == true){return;}switch (AttackHp){case 1://同步所有角色受伤:枪伤photonView.RPC("GetGunHitRPC", RpcTarget.All);   break;case 2://同步所有角色受伤:爆炸伤 —— 火箭筒和手雷共用photonView.RPC("GetBoomHitRPC", RpcTarget.All);  break;default:Debug.Log("------------ERROR");break;}Score += addScore;p.SetScore(Score);}
}

缺点:火箭筒弹道很偏,可能和人物模型的呼吸晃动有关,小弟暂时无能为力。日后改进

祝大家周五愉快,拜拜┏(^0^)┛ 


狗剩的成长日记:

Unity之PUN2插件实现多人联机射击游戏_unity pun2-CSDN博客文章浏览阅读1.5k次,点赞21次,收藏29次。周五的下午永远要比周六幸福,周五好啊大家有在认真摸鱼吗。前两天我突发奇想想做联机游戏,就去找教程,肝了一天终于做出来了。先说一下搜寻资料过程中找到的实现游戏联机暂时就记录了这11个,做的这个实例是通过PUN2实现的,先看一下效果:个人感觉这套模型和这个教程泰裤辣,能跟着做完这个游戏Demo也是很开心的,下面依然以博客的形式记录实现这个游戏的过程。_unity pun2https://blog.csdn.net/qq_48512649/article/details/136249522Unity之PUN实现多人联机射击游戏的优化(Section 1)_unity pun2 角色名称-CSDN博客文章浏览阅读1.5k次,点赞24次,收藏29次。关于优化了哪几个小点:点击开始游戏玩家可以输入自己的昵称;进入到房间后玩家对应的昵称也会同步显示到房间列表上;和朋友一起玩的时候他说会卡进房间的模型里建议我加上跳跃功能,我就给加上了,顺便加了一个按住Shift和方向键进行加速跑;同时按住Tab键会显示出计分板,这个计分板是按照射击命中次数来计分的。_unity pun2 角色名称https://blog.csdn.net/qq_48512649/article/details/136615629Unity之PUN实现多人联机射击游戏的优化(Section 2)_unity photon 多人射击游戏-CSDN博客文章浏览阅读1k次,点赞21次,收藏34次。这几周都给我布置任务了,最近可忙。今天就来兑现诺言:有天我查看这个游戏包的资源,居然发现了手雷和其他很多武器,而且手雷的爆炸脚本是写好的,那就试着加一个手雷功能。看一下效果手雷爆炸的原理呢就像小编之前写的物理系统里面的小实例一样:Unity之物理系统_unity 物理系统-CSDN博客专栏的上一篇角色控制器控制角色移动跳崖,这一篇来说说Unity的物理系统。本篇小编还要带大家做一个碰撞检测效果实例,先放效果图:流星撞击地面产生爆炸效果。_unity 物理系统。_unity photon 多人射击游戏https://blog.csdn.net/qq_48512649/article/details/137267066


相关文章:

Unity之PUN实现多人联机射击游戏的优化(Section 3)

目录 &#x1f4a3;一、准备工作 &#x1f4a3;二、生成弹头脚本的编写 &#x1f4a3;三、实现发射和伤害同步 手雷都加了在给狗剩加个火箭筒不过分吧。效果看GIF动图&#xff0c;分别是单机和联机的效果。 添加火箭筒依旧是在原有的基础上更改&#xff0c;我查看火箭筒模型…...

PDF锐化

PDF Shaper Ultimate(pdf转图片) 编辑->添加文件->选中一个要处理的pdf 操作->转换->PDF转为图片 ComicEnhancerPro设置(把图片锐化) PDF Shaper Ultimate(图片转pdf) 编辑-添加图片->选中所有锐化处理后的图片 转换->图片转为pdf&#xff08;会把所有图…...

【python和java】

如何理解java和python的不同&#xff0c;在java中&#xff0c;先有类&#xff0c;类生出对象&#xff0c;对象承载数据。而python是直接数据&#xff0c;没有类的概念 理解 Java 和 Python 在面向对象编程&#xff08;OOP&#xff09;方面的不同&#xff0c;关键在于理解它们各…...

C盘满了怎么办,清理工具TreeSize

TreeSize是一款强大的磁盘空间分析工具&#xff0c;它可以帮助用户轻松地找出电脑中占用空间最多的文件和程序&#xff0c;从而让用户进行针对性地删除或卸载。 占用空间很小 下载链接&#xff1a;https://pan.quark.cn/s/bea23ed6b1d3...

【vue】watch 侦听器

watch&#xff1a;可监听值的变化&#xff0c;旧值和新值 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><titl…...

校招生如何准备软件测试、测试开发岗位的面试?

校招生如何准备软件测试、测试开发岗位的面试&#xff1f; 求职建议 大家都很困惑如何学习测试&#xff1f;如何准备测试方面的面试&#xff1f; 我有朋友是做研发的&#xff0c;他认为测试不用准备&#xff0c;直接用开发的简历就行。也有人认为要学习一些测试理论&#xf…...

蓝桥杯抱佛脚篇~

文章目录 基础语法输入输出集合(set&#xff09;排序 基础语法 输入输出 # 输入一个数 nint(input())# 输入两、三个数&#xff0c;例如&#xff1a;1 2 或者 1 2 3 x,y map(int,input().split())# 输入数组 # ——— 1 —— nums[int(i) for i in input().split()] print(n…...

基于springboot的大学城水电管理系统源码数据库

基于springboot的大学城水电管理系统源码数据库 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了大学城水电管理系统的开发全过程。通过分析大学城水电管理系统管理的不足&#xff0c;创建了一个计算机管理大学城水…...

AI大模型探索之路-应用篇2:Langchain框架ModelIO模块—数据交互的秘密武器

目录 前言 一、概述 二、Model 三、Prompt 五、Output Parsers 总结 前言 随着人工智能技术的不断进步&#xff0c;大模型的应用场景越来越广泛。LangChain框架作为一个创新的解决方案&#xff0c;专为处理大型语言模型的输入输出而设计。其中&#xff0c;Model IO&#…...

【SSH】群晖开启ssh访问

群晖开启ssh访问 假设 你需要设置群晖 账号 test-user 开启ssh访问 设置 你的 test-user 为管理员权限 否则你无法通过cmd 面板 连接访问 群晖你需要哪个账号 就使用哪个账号终端 cmd连接 否则需要考虑后续创建 rsa 公密钥文件的 所属权 问题账号密码连接登录终端 ssh -p 端…...

Vue 移动端(H5)项目怎么实现页面缓存(即列表页面进入详情返回后列表页面缓存且还原页面滚动条位置)keep-alive缓存及清除keep-alive缓存

一、需求 产品要求&#xff1a;Vue移动端项目进入列表页&#xff0c;列表页需要刷新&#xff0c;而从详情页返回列表页&#xff0c;列表页则需要缓存并且还原页面滚动条位置 二、实现思路 1、使用Vue中的keep-alive组件&#xff0c;keep-alive提供了路由缓存功能 2、因为我项…...

【MVCC】深入浅出彻底理解MVCC

MVCC概述 MVCC&#xff08;Multi-Version Concurrency Control&#xff09;即多版本并发控制。主要是为了提高数据库的并发性能而提供的&#xff0c;采用了不加锁的方式处理读-写并发冲突&#xff0c;确保了任何时刻的读操作都是非阻塞的。只需要很小的开销&#xff0c;就可以…...

【问题解决】ubuntu安装新版vscode报code-insiders相关错误

问题 目前 vscode官网 最新的包为 insiders_1.89.0-1712297812_amd64.deb &#xff0c;双击或者使用sudo dpkg -i code-insiders_1.89.0-1712297812_amd64.deb安装后报错&#xff0c;执行其他命令也报错。 安装环境&#xff1a;ubuntu18.04 dpkg: 处理软件包 code-insiders (…...

【Python】面向对象(专版提升2)

面向对象 1. 概述1.1面向过程1.2 面向对象 2. 类和对象2.1 语法2.1.1 定义类2.1.2 实例化对象 2.2 实例成员2.2.1 实例变量2.2.2 实例方法2.2.3 跨类调用 3. 三大特征3.1 封装3.1.1 数据角度3.1.2 行为角度3.1.3 案例:信息管理系统3.1.3.1 需求3.1.3.2 分析3.1.3.3 设计 3.2 继…...

Vscode设置滚轮进行字体大小的调节

Vscode设置滚轮进行字体大小的调节 正常的话按 ctrl 或者 ctrl - 进行字体的大小调节 1.打开Vscode&#xff0c;找打设置的图标&#xff0c;在点击设置&#xff0c;或者直接使用快捷键&#xff0c;【ctrl ,】 2. 在搜索框搜索Font Ligatures 3.双击进入settings.json ,找到如…...

【QT入门】Qt自定义控件与样式设计之控件提升与自定义控件

【QT入门】Qt自定义控件与样式设计之控件提升与自定义控件 往期回顾 【QT入门】Qt自定义控件与样式设计之QProgressBar用法及qss-CSDN博客 【QT入门】 Qt自定义控件与样式设计之QSlider用法及qss-CSDN博客 【QT入门】Qt自定义控件与样式设计之qss的加载方式-CSDN博客 一、最终…...

Spring Validation解决后端表单校验

NotNull&#xff1a;从前台传递过来的参数不能为null,如果为空&#xff0c;会在控制台日志中把message打印出来 Range&#xff1a;范围&#xff0c;最大多少&#xff0c;最小多少 Patten&#xff0c;标注的字段值必须符合定义的正则表达式&#xff08;按照业务规则&#xff0…...

Harmony鸿蒙南向驱动开发-UART接口使用

功能简介 UART指异步收发传输器&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;&#xff0c;是通用串行数据总线&#xff0c;用于异步通信。该总线双向通信&#xff0c;可以实现全双工传输。 两个UART设备的连接示意图如下&#xff0c;UART与其他模块一…...

【示例】MySQL-事务控制示例:账户转账-savepoint关键字

前言 本文讲述MySQL中的事务&#xff0c;以账户转账为例&#xff0c;体会事务的概念&#xff0c;并讲解事务相关的一个关键字用法&#xff1a;savepoint 示例 数据准备 drop table if exists account;create table account(id int primary key AUTO_INCREMENT comment ID,n…...

STM32使用标准版RT-Thread,移植bsp中的板文件后,想使用I/O设备模型,使用串口3或者串口4收发时,发现串口3或者串口4没反应

STM32移植RT-Thread出现的问题及解决办法 问题原因解决方法 问题 使用标准版RT-Thread,移植bsp中的板文件后&#xff0c;想使用I/O设备模型&#xff0c;使用串口3或者串口4收发时&#xff0c;发现串口3或者串口4没反应。出现问题&#xff1a;程序一直跑在 while (__HAL_UART_…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...