Unity之PUN实现多人联机射击游戏的优化(Section 2)
目录
🎮一、准备工作
🎮二、实现手雷投掷动作
🎮三、手雷投掷同步
💤3.1 photonView.RPC
🎮四、同步手雷伤害
这几周都给我布置任务了,最近可忙。现在终于有机会更新了,也谢谢大家的阅读,我们一起进步。如果前面两篇大家有没有看到的可以在本篇文章末尾点击链接查看,资源包也在博客里有链接。
今天就来兑现诺言:有天我查看这个游戏包的资源,居然发现了手雷和其他很多武器,而且手雷的爆炸脚本是写好的,那就试着加一个手雷功能。看一下效果
手雷爆炸的原理呢就像小编之前写的物理系统里面的小实例一样:
Unity之物理系统_unity 物理系统-CSDN博客文章浏览阅读1.3k次,点赞22次,收藏20次。专栏的上一篇角色控制器控制角色移动跳崖,这一篇来说说Unity的物理系统。本篇小编还要带大家做一个碰撞检测效果实例,先放效果图:流星撞击地面产生爆炸效果。_unity 物理系统https://blog.csdn.net/qq_48512649/article/details/135600857
手雷扔出去爆炸手雷的预设体会销毁对应的则生成爆炸特效的预设体。给爆炸特效加上碰撞组件,爆炸特效生成的一瞬间就会产生把玩家击飞的效果,随后爆炸特效预设体跟着消失。这个资源里边自带的脚本已经帮我们实现好了。
放在单击游戏上实现起来很简单,但是对于小编来说最难的是数据同步,没办法既然想实现这个功能就试着去摸索。
看一下踩过的坑,比如下面的图片,其中一个玩家画面里就会看到一个尸体在动,还会打人!!!!这就是数据同步没有做好,就会很搞笑
修改之后,就小编目前的测试来说可以实现同步了(在公司只能开小窗口测试doge.jpg)
一、准备工作
首先来看资源包中手雷预设体的位置,这里所挂载的组件和数值大家可以进行参考
这是爆炸特效预设体的位置以及其挂载的组件:
玩家预设体上有一个手雷生成点,当我们按下投手雷时就设定在这个点生成手雷。缺点是只能朝着这个角度进行投掷。
二、实现手雷投掷动作
在前面两期代码的基础上,我们在PlayerController脚本来添加按下Q键实现投掷手雷的功能,这里做了一个设定是每隔5秒可以投一次手雷。
//定义布尔值判断手雷是否可以进行投掷
private bool boolHandGrenade = false;//角色操作:在判断为本机玩家操作的前提下
public void InputCtl()
{//按ESC退出游戏// if (Input.GetKeyDown(KeyCode.Escape))// {// Application.Quit();// }if (Input.GetKeyDown(KeyCode.Q)){if (boolHandGrenade == false){boolHandGrenade = true;//每隔5秒才可以扔一次Invoke("boolThrowHandGrenade", 5f);//播放投掷手雷动作动画ani.Play("Grenade_Throw");StopAllCoroutines();//开启协程同步手雷的生成,在三部分讲StartCoroutine(AttHandGrenade());}}
}//更改判断手雷是否可以进行投掷的布尔值
void boolThrowHandGrenade()
{boolHandGrenade = false;
}
上面这个代码块只实现了玩家投掷手雷时所做的动作,但是要生成手雷要在所有玩家画面上都要进行同步生成,我们接着往下看。
三、手雷投掷同步
手雷预设体生成的代码小编写在Gun脚本里了,和子弹生成的逻辑差不多。代码写好后我们按准备工作中的内容把手雷生成点和手雷预设体设置好。
//枪的脚本
public class Gun : MonoBehaviour
{public int BulletCount = 10;public GameObject bulletPrefab;public GameObject casingPreafab;public Transform bulletTf;public Transform casingTf;//手雷public GameObject handGrenadePrefab;//手雷生成点public Transform handGrenadeTf;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 AttGrenade(){//实例化一个手雷GameObject handGrenadeObj = Instantiate(handGrenadePrefab,handGrenadeTf.transform.position,handGrenadeTf.transform.rotation);handGrenadeObj.GetComponent<Rigidbody>().AddForce(transform.forward * 1,ForceMode.Impulse); //投掷速度 让中心点跟枪口位置可自行调整摄像机的偏移值}
}
手雷生成的代码写好后我们来设置同步。在之前第二部分中,我们现在来讲
//开启协程同步手雷的生成,在三部分讲
StartCoroutine(AttHandGrenade());//协程方法实现
IEnumerator AttHandGrenade()
{yield return new WaitForSeconds(0.5f);// 3.1 photonView.RPC 中讲解photonView.RPC("throwHandGrenade", RpcTarget.All); //所有玩家执行 AttackRpc 函数
}[PunRPC]
public void throwHandGrenade()
{gun.AttGrenade(); //这里会执行Gun脚本中的AttGrenade()方法
}
3.1 photonView.RPC
进入源代码我们来看这一方法:参数有三个(方法名、目标群体、参数)
这句代码的意思是所标注的目标群体一块执行我们自己写的方法,下图是目前群体的枚举类型:
第三个参数 params object[] parameters 小编看到它最终是存到一个 Hashtable 类型里,我们现在只用到了前两个参数。
对应到我们的代码中意思就是当前房间所有玩家同步其中一个人所生成的手雷。
四、同步手雷伤害
依然在PlayerController脚本里,我们给爆炸特效一个Boom的图层标签,用来检测它是否与玩家发生碰撞。
//监听发生碰撞: 只监听发生碰撞的一瞬间
private void OnCollisionEnter(Collision collision) //参数 collision 就是你碰撞到的物体的碰撞信息
{//给地面一个图层"Ground" collision.collider.tag == "Ground" 可以判断物体是否踩在地面上if (collision.collider.tag == "Boom"){GetHit(localPlayer,3,2);}
}
如果发生碰撞了就执行GetHit方法,这里我们给GetHit方法加了参数,因为爆炸和枪击的伤害值和得分是不同设定的,我们通过参数来进行区分。伤害值大家可以根据自己的想法设定。
上图是枪击执行的GetHit方法。
//同步所有角色受伤: 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);}[PunRPC]public void GetGunHitRPC(){CurHp -= 1; //扣血if (CurHp <= 0){CurHp = 0;isDie = true;}if (photonView.IsMine){Game.uiManager.GetUI<FightUI>("FightUI").UpdateHp(CurHp, MaxHp);Game.uiManager.GetUI<FightUI>("FightUI").UpdateBlood();if (CurHp == 0){Invoke("gameOver", 3); //3秒后显示失败界面 }}}[PunRPC]public void GetBoomHitRPC(){CurHp -= 3; //扣血if (CurHp <= 0){CurHp = 0;isDie = true;}if (photonView.IsMine){Game.uiManager.GetUI<FightUI>("FightUI").UpdateHp(CurHp, MaxHp);Game.uiManager.GetUI<FightUI>("FightUI").UpdateBlood();if (CurHp == 0){Invoke("gameOver", 3); //3秒后显示失败界面 }}}
GetGunHitRPC 和 GetBoomHitRPC 除了伤害值不同其他逻辑都相同,小编本来想合成一个共用的方法奈何没成功,目前只能shi山堆积了。如果大家有更好的写法小编还要虚心向大家请教。
前面两篇博客的链接:
Unity之PUN2插件实现多人联机射击游戏_unity pun2-CSDN博客文章浏览阅读1.3k次,点赞20次,收藏24次。周五的下午永远要比周六幸福,周五好啊大家有在认真摸鱼吗。前两天我突发奇想想做联机游戏,就去找教程,肝了一天终于做出来了。先说一下搜寻资料过程中找到的实现游戏联机暂时就记录了这11个,做的这个实例是通过PUN2实现的,先看一下效果:个人感觉这套模型和这个教程泰裤辣,能跟着做完这个游戏Demo也是很开心的,下面依然以博客的形式记录实现这个游戏的过程。_unity pun2https://blog.csdn.net/qq_48512649/article/details/136249522Unity之PUN实现多人联机射击游戏的优化(Section 1)_unity pun2 角色名称-CSDN博客文章浏览阅读1.5k次,点赞23次,收藏28次。关于优化了哪几个小点:点击开始游戏玩家可以输入自己的昵称;进入到房间后玩家对应的昵称也会同步显示到房间列表上;和朋友一起玩的时候他说会卡进房间的模型里建议我加上跳跃功能,我就给加上了,顺便加了一个按住Shift和方向键进行加速跑;同时按住Tab键会显示出计分板,这个计分板是按照射击命中次数来计分的。_unity pun2 角色名称https://blog.csdn.net/qq_48512649/article/details/136615629今天先到这里,拜拜┏(^0^)┛
相关文章:
Unity之PUN实现多人联机射击游戏的优化(Section 2)
目录 🎮一、准备工作 🎮二、实现手雷投掷动作 🎮三、手雷投掷同步 💤3.1 photonView.RPC 🎮四、同步手雷伤害 这几周都给我布置任务了,最近可忙。现在终于有机会更新了,也谢谢大家的阅读&a…...
多叉树题目:N 叉树的层序遍历
文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题:N 叉树的层序遍历 出处:429. N 叉树的层序遍历 难度 4 级 题目描述 要求 给定一个 N 叉树的根结点 root \texttt{root} root…...
时序数据库IoTDB:功能详解与行业应用
一文读懂时序数据库 IoTDB。 01 为什么需要时序数据库 解释时序数据库前,先了解一下何谓时序数据。 时序数据,也称为时间序列数据,是指按时间顺序记录的同一统计指标的数据集合。这类数据的来源主要是能源、工程、交通等工业物联网强关联行业…...
信息系统项目管理师——第18章项目绩效域管理(一)
本章节内容属于第四版新增知识,为PMBOK第七版专有,选择、案例、论文都会考,属于比较重要的章节。 选择题,稳定考3分左右,新教材基本考课本原话,需要多读课本,多刷题。 案例题,考的概…...
WebSocket用户验证
在WebSocket中,如何携带用户的验证信息 一、在OnMessage中进行验证 客户端在连接到服务器后,客户端通过发送消息,服务器端在OnMessage方法中,进行信息验证,这种方式需要将用户身份验证及接收用户消息进行混合处理&am…...
NOSQL(非关系型数据库)的优缺点有哪些?
优点: 高度灵活且可扩展:NoSQL数据库不受固定数据模型的限制,可以根据应用需求灵活设计数据结构,轻松应对大规模数据集。此外,它支持分布式架构,具有出色的水平扩展能力,能够高效地处理大量数据…...
个人推荐Redis比较好的一种使用规范
随着对个人项目的不断开发、迭代和重构,博主在这个过程中总结出了一套使用redis的较好的规范。主要包含Redis的key命名规范和Redis代码规范。 主要内容 主要包含以下几个内容: 同一应用的key在最前面添加统一的前缀,如应用名; 案…...
【教程】宝塔default.db占用空间几十g解决方法|宝塔占用磁盘空间特别大解决方法|宝塔磁盘被占满怎么清理
目录 一、前言二、排查问题三、解决方法 一、前言 用过宝塔创建网站,大家应该都非常熟悉,但是用随着用的时间越来越多,宝塔所占用的空间也越来越多,不停的加大数据盘都没有用,我原先买了30G够用了,随着时间…...
Unity类银河恶魔城学习记录11-15 p117 Ice and Fire item Effect源代码
Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili IceAndFire_Controller.cs using System.Collections; using System.Coll…...
Qt QML的枚举浅用
QML的枚举用法 序言概念命名规则在QML定义枚举的规范 用法QML的枚举定义方法供QML调用的,C的枚举定义方法 序言 概念 QML的枚举和C的其实差不多,但是呢,局限比较多,首先不能在main.qml里定义,也不能在子项中定义。 …...
设计模式:单例模式六种实现
单例模式有多种实现方式,每种方式都有其设计思想、优缺点以及适用的使用场景。以下是一些常见的单例实现方式: 1. 懒汉式(线程不安全) 设计思想 这种实现方式采用了类加载的懒加载机制来保证单例只在第一次使用时被创建。 实现代码 public class Singleton {private s…...
Mybatis-Plus05(分页插件)
分页插件 MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能 1. 添加配置类 Configuration MapperScan("com.atguigu.mybatisplus.mapper") //可以将主类中的注解移到此处 public class MybatisPlusConfig {Bean public MybatisPlusIntercepto…...
python爬取B站视频
参考:https://cloud.tencent.com/developer/article/1768680 参考的代码有点问题,请求头需要修改,上代码: import requests import re # 正则表达式 import pprint import json from moviepy.editor import AudioFileClip, Vid…...
深度学习500问——Chapter05: 卷积神经网络(CNN)(2)
文章目录 5.6 有哪些池化方法 5.7 1x1卷积作用 5.8 卷积层和池化层有什么区别 5.9 卷积核是否一定越大越好 5.10 每层卷积是否只能用一种尺寸的卷积核 5.11 怎样才能减少卷积层参数量 5.12 在进行卷积操作时,必须同时考虑通道和区域吗 5.13 采用宽卷积的好处有什么 …...
基于单片机的测时仪系统设计
**单片机设计介绍,基于单片机的测时仪系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的测时仪系统设计是一个结合了单片机技术与测时技术的综合性项目。该设计的目标是创建一款精度高、稳定性强且…...
鸿蒙原生应用开发-网络管理Socket连接(三)
应用通过TLS Socket进行加密数据传输 开发步骤 客户端TLS Socket流程: 1.import需要的socket模块。 2.绑定服务器IP和端口号。 3.双向认证上传客户端CA证书及数字证书;单向认证只上传CA证书,无需上传客户端证书。 4.创建一个TLSSocket连接…...
【Java EE】关于Maven
文章目录 🎍什么是Maven🌴为什么要学Maven🌲创建⼀个Maven项目🌳Maven核心功能🌸项目构建🌸依赖管理 🍀Maven Help插件🎄Maven 仓库🌸本地仓库🌸私服 ⭕总结 …...
每日一题:C语言经典例题之反转数
题目描述 给定一个整数,请将该数各个数位上的数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零。 题目描述 给定一个整数,请将该数各个数位上的数字反转得到一个…...
RESTfull接口访问Elasticsearch
【数据库的健康值】 curl -X GET "ip:9200/_cat/health" 【查看所有索引】 curl -X GET "ip:9200/_cat/indices?v" 【查看索引index_name】 curl -X GET "ip:9200/索引?pretty" 【创建索引/文档】 PUT "ip:9200/索引/文档id" {请…...
NoSQL之Redis
目录 一、关系型数据库与非关系型数据库 1.关系数据库 2.非关系数据库 2.1非关系型数据库产生背景 3.关系型数据库与非关系型数据区别 (1)数据存储方式不同 (2)扩展方式不同 (3)对事物性的支持不同 …...
double二分(P3743 小鸟的设备)
题目:P3743 小鸟的设备 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 代码: #include<bits/stdc.h> using namespace std; const int N2e510; double a[N],b[N]; int n; double p;bool check(double mid) {double sum0.0;for(int i1;i<n;i){if(a[i]*mi…...
【独立开发前线】Vol.36 为什么从2023年开始,独立开发者越来越多了?
不知道你有没有观察到,从2023年开始,国内的独立开发者越来越多了。 之前独立开发者是一个非常小众的群体,但现在很多互联网从业者都瞄准了这个方向,包括程序员、产品经理,运营等等。 我想可能是这样几个原因…...
GPT4不限制使用次数了!GPT5即将推出了!
今天登录到ChatGPT Plus账户,出现了如下提示: 已经没有了数量和时间限制的提示。 更改前:每 3 小时限制 40 次(团队计划为 100 次);更改后:可能会应用使用限制。 GPT-4放开限制 身边订阅了Ch…...
物联网实战--入门篇之(六)嵌入式-WIFI驱动(ESP8266)
目录 一、WIFI简介 二、基础网络知识 三、思路讲解 四、代码分析 4.1 状态机制 4.2 客户端连接 4.3 应用数据接收处理 4.4 数据发送 4.5 主函数调用 4.6 网络连接ID分配 五、总结 一、WIFI简介 WIFI在我们生活中太常见了,手机电脑都可以用WiFi连接路由器进行上…...
Java并发编程基础面试题详细总结
1. 什么是线程和进程? 1.1 何为进程? 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。 在 Java 中,当我们启动 main 函数时其实就是启动了一个…...
EKO / 砍树
暴力是不行的,还得是二分吧 题目描述 伐木工人 Mirko 需要砍 M 米长的木材。对 Mirko 来说这是很简单的工作,因为他有一个漂亮的新伐木机,可以如野火一般砍伐森林。不过,Mirko 只被允许砍伐一排树。 Mirko 的伐木机工作流程如下&a…...
Kafka面试宝典
1 Kafka基础面试篇 Kafka的那些设计让它有如此高的性能? 1.partition,producer和consumer端的批处理:提高并行度;2.页缓存:大量使用页缓存,内存操作比磁盘操作快很多,数据写入直接写道页缓存,由操作系统负责刷盘,数据读取也是直接命中页缓存,从内存中直接拿到数据;…...
Redis性能管理
目录 1、内存碎片如何产生的? 2、跟踪内存碎片率对理解Redis实例的资源性能是非常重要的 3、解决碎片率大的问题 二、内存使用率 1、避免内存交换发生的方法 2、内回收key 三、缓存的穿透、击穿、雪崩 #查看Redis内存使用方法 info memory #进入数据库查看 re…...
计算机网络:局域网的数据链路层
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...
Linux常见命令简介
Linux运行级别 六种运行级别: 0、关机 1、单用户(可用来找回密码) 2、多用户无网络 3、多用户有网络(多用于工作环境) 4、预留 5、图形界面(多用于学习环境) 6、重…...
网站设计特色/seo快速排名软件推荐
前面的《配置中心》和《服务注册&服务提供者》这两篇分别讲解了配置中心和服务提供者,但是服务提供者使用的配置文件还是本地的,没有使用配置中心的配置文件。今天看看如何实现服务提供者使用配置中心的配置文件。新建项目sc-eureka-client-provider…...
杭州网站建设开发有限公司/搜索引擎是网站吗
参考http://www.cnblogs.com/showson/p/5602460.html 一样的解法,注意到在后面添加/删除与树形结构的互相转换。 【code】 http://uoj.ac/submission/77367转载于:https://www.cnblogs.com/showson/p/5602502.html...
分析网站做的好坏/seo入门培训学多久
1.新建访问的控制器动作返回视图,在视图中使用easyui的treegrid插件来得到后台得到的json数据显示多级菜单 public ActionResult Menu(){return View();} View Code视图: {ViewBag.Title "Menu";Layout "~/Views/Shared/_GridView.csht…...
小超人成都网站建设/营销型网站模板
漏洞介绍 Struts2在使用Freemarker模块引擎的时候,同时允许解析OGNL表达式。导致用户输入的数据本身不会被OGNL解析,但是由于被Freemarker解析一次后变成离开一个表达式,被OGNL解析第二次,导致任意命令执行漏洞。 影响版本 Struts 2.0.1 - Struts 2.3.33、Struts 2.5 - Stru…...
英文企业网站建设/网站外链优化方法
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处、作者信息和本声明。否则将追究法律责任。http://caoyameng.blog.51cto.com/4975863/1359732运维自动化是2010年开始炒得很热的一个概念,也让很多工程师、用人单位瞎激动了很久…...
做网站资讯/张北网站seo
dubboSPI实现思想跟javaspi的思想差不多javaspi是ServiceLoad 而dubbo自己写的是ExtensionLoader SPI接口定义 Documented Retention(RetentionPolicy.RUNTIME) Target({ElementType.TYPE}) public interface SPI {String value() default "";//扩展点的key } 说明&a…...