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秒后显示失败界面       }}}
GetGunHitRPCGetBoomHitRPC 除了伤害值不同其他逻辑都相同,小编本来想合成一个共用的方法奈何没成功,目前只能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^)┛

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/793788.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaSE-11笔记【多线程2(+2024新)】

文章目录 6.线程安全6.1 线程安全问题6.2 线程同步机制6.3 关于线程同步的面试题6.3.1 版本16.3.2 版本26.3.3 版本36.3.4 版本4 7.死锁7.1 多线程卖票问题 8.线程通信8.1 wait()和sleep的区别&#xff1f;8.2 两个线程交替输出8.3 三个线程交替输出8.4 线程通信-生产者和消费者…

Tailwind 4.0 即将到来:前端开发的“速度与激情”

随着前端开发技术的不断进步&#xff0c;我们每天都在寻找更快、更简洁的解决方案来提升我们的开发效率和用户体验。今天&#xff0c;我要为大家介绍一项令人振奋的新技术进展——Tailwind 4.0的来临&#xff01; 对于经常使用Tailwind的朋友们来说&#xff0c;这个消息无疑是激…

阿里云短信服务业务

一、了解阿里云用户权限操作 1.注册账号、实名认证&#xff1b; 2.使用AccessKey 步骤一 点击头像&#xff0c;权限安全的AccessKey 步骤二 设置子用户AccessKey 步骤三 添加用户组和用户 步骤四 添加用户组记得绑定短信服务权限 步骤五 添加用户记得勾选openApi访问 添加…

Educational Codeforces Round 162 (Rated for Div. 2) ----- E. Count Paths --- 题解

E. Count Paths&#xff1a; 题目大意&#xff1a; 思路解析&#xff1a; 根据题目中定义的美丽路径&#xff0c;我们可以发现路径只有两种情况&#xff1a; 当前结点作为起始结点&#xff0c;那我们只需要知道它的子树下有多少个相同颜色的结点&#xff0c;并且相同颜色的结…

使用 HTMX 和 Bun 进行全栈 Web 开发

将 HTMX 放在前端&#xff0c;Bun 放在后端&#xff0c;然后将它们与 Elysia 和 MongoDB 连接起来&#xff0c;形成快速便捷的技术栈&#xff0c;使开发 Web 应用程序变得轻而易举。 Bun 和 HTMX 是目前软件领域最有趣的两个事情。 Bun 是一个速度极快的一体化服务器端 JavaSc…

如何创建一个TCP多人聊天室?

一、什么是TCP&#xff1f; TCP&#xff08;Transmission Control Protocol&#xff09;是一种可靠的 面向连接的协议 &#xff0c;可以保证数据在传输过程中不会丢失、重复或乱序。 利用TCP实现简单聊天程序&#xff0c;需要客户端和服务器端之间建立TCP连接&#xff0c;并通…

MATLAB近红外光谱分析技术应用

郁磊副教授&#xff0c;主要从事MATLAB编程、机器学习与数据挖掘、数据可视化和软件开发、生理系统建模与仿真、生物医学信号处理&#xff0c;具有丰富的实战应用经验&#xff0c;主编《MATLAB智能算法30个案例分析》、《MATLAB神经网络43个案例分析》相关著作。已发表多篇高水…

C# MES通信从入门到精通(8)——C#调用Webservice服务进行数据交互

前言 在上位机开发领域,使用webservice来访问客户的终端Mes系统是一项必备的技能,本文详细介绍了如何在c#中调用webservice服务,不仅介绍了使用添加服务引用直接调用webservice中的方法外还介绍了使用http的post方法调用webservice方法,过程详细且均为实战经验总结,对于初…

港口核心!达梦数据助力上港集团罗泾码头 I-TOS 系统升级改造

港口作为交通运输的枢纽和联通世界的窗口&#xff0c;肩负着带动区域经济发展及服务国际经贸的双重责任。在信息化浪潮推动下&#xff0c;自动化、数字化、智能化成为港口航运业转型发展的关键。 达梦数据积极推进港口数字化转型升级 &#xff0c;助力上港集团罗泾码头实现 I-T…

青蛙过河(二分+前缀和)

题目描述 小青蛙住在一条河边&#xff0c;它想到河对岸的学校去学习。小青蛙打算经过河里的石头跳到对岸。 河里的石头排成了一条直线&#xff0c;小青蛙每次跳跃必须落在一块石头或者岸上。不过&#xff0c;每块石头有一个高度&#xff0c;每次小青蛙从一块石头起跳&#xf…

[问题记录] oracle问题汇总记录

plsql问题 1、oracle-initialization error could not locate OCI.dll 下载plsql客户端后&#xff0c;登录显示如图所示的错误 解决方法&#xff0c;点击下方链接&#xff0c;下载64位客户端 Instant Client for Microsoft Windows (x64) 64-bit (oracle.com) 2、显示中文乱…

【资源分享】最全ChatGPT镜像免梯子

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…

leetCode第十题 : 正则表达式匹配 动态规划【10/1000 python】

&#x1f464;作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 LeetCode解锁1000题: 打怪升级之旅htt…

wordpress全站开发指南-面向开发者及深度用户(全中文实操)--初尝php

初尝php 打开你下载的wordpress文件夹&#xff0c;如果你用的xampp那它就在xampp安装的文件夹–htdocs文件夹–你可以新建一个test文件夹–新建一个test.php文件 <html><head><title>First attempt at PHP</title></head><body><?ph…

Spring注解开发和XML开发

目录 Spring简介发展史Spring Framework系统架构spring 核心概念IOC、IOC容器、Bean、DIIOC快速入门DI快速入门 IOCBean基础配置id与class属性name属性scope属性 Bean的实例化构造方法静态工厂实例工厂FactoryBean的使用&#xff08;工厂实例的简化&#xff09; Bean的生命周期…

【Qt】:常用控件(三:按钮类)

常用控件&#xff08;三&#xff09; 一.Push Button二.Radio Buttion三.Check Box 一.Push Button 使⽤ QPushButton 表⽰⼀个按钮.这也是当前我们最熟悉的⼀个控件了.QPushButton继承⾃QAbstractButton .这个类是⼀个抽象类.是其他按钮的⽗类. QAbstractButton 中,和 QPushBu…

Qt中出现中文乱码的原因以及解决方法

Qt专栏&#xff1a;http://t.csdnimg.cn/C2SDN 目录 1.引言 2.原因分析 3.源文件的编码格式修改方法 4.程序内部使用的默认编码格式修改方法 5.QString转std::string的方法 6.总结 1.引言 在编写Qt程序的时候&#xff0c;或多或少都可能遇到用QString时候&#xff0c;明明…

Docker 安装 | 部署MySQL 8.x 初始设置

1、准备工作 如果不想看前面的废话请直接右边目录跳到 运行容器 处 默认你已经有 docker 环境。 Windows 推荐 Docker Desktop &#xff08;下载地址&#xff09;并基于 WSL2 运行 Docker 环境 mac 推荐 Orbstack &#xff08;下载地址&#xff09;&#xff08;这个很节省资源&…

控制台RPG 游戏实现双缓冲无屏闪,玩家类,地图类

重整控制台RPG——双缓冲无屏闪以及第一个无中生有的地图类&#xff0c;玩家类_哔哩哔哩_bilibili 是鄙人解说鄙人的代码 #include <iostream> #include <string.h> #include <windows.h>#define KEY_DOWN(vKey) ((GetAsyncKeyState(vKey) & 0x8000) ?…

Stable diffusion 加载扩展列表报错解决方法

项目场景&#xff1a; 在使用Stable diffusion webui时&#xff0c;使用扩展列表出现错误 问题描述 点击loadfrom后&#xff0c;出现加载扩展列表报错 原因分析&#xff1a; 下载的扩展的时候&#xff0c;都是github 的url&#xff0c;需要科学上网&#xff0c;如果不能科学…