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

PDF锐化
PDF Shaper Ultimate(pdf转图片) 编辑->添加文件->选中一个要处理的pdf 操作->转换->PDF转为图片 ComicEnhancerPro设置(把图片锐化) PDF Shaper Ultimate(图片转pdf) 编辑-添加图片->选中所有锐化处理后的图片 转换->图片转为pdf(会把所有图…...
【python和java】
如何理解java和python的不同,在java中,先有类,类生出对象,对象承载数据。而python是直接数据,没有类的概念 理解 Java 和 Python 在面向对象编程(OOP)方面的不同,关键在于理解它们各…...

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

【vue】watch 侦听器
watch:可监听值的变化,旧值和新值 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><titl…...

校招生如何准备软件测试、测试开发岗位的面试?
校招生如何准备软件测试、测试开发岗位的面试? 求职建议 大家都很困惑如何学习测试?如何准备测试方面的面试? 我有朋友是做研发的,他认为测试不用准备,直接用开发的简历就行。也有人认为要学习一些测试理论…...
蓝桥杯抱佛脚篇~
文章目录 基础语法输入输出集合(set)排序 基础语法 输入输出 # 输入一个数 nint(input())# 输入两、三个数,例如:1 2 或者 1 2 3 x,y map(int,input().split())# 输入数组 # ——— 1 —— nums[int(i) for i in input().split()] print(n…...
基于springboot的大学城水电管理系统源码数据库
基于springboot的大学城水电管理系统源码数据库 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了大学城水电管理系统的开发全过程。通过分析大学城水电管理系统管理的不足,创建了一个计算机管理大学城水…...

AI大模型探索之路-应用篇2:Langchain框架ModelIO模块—数据交互的秘密武器
目录 前言 一、概述 二、Model 三、Prompt 五、Output Parsers 总结 前言 随着人工智能技术的不断进步,大模型的应用场景越来越广泛。LangChain框架作为一个创新的解决方案,专为处理大型语言模型的输入输出而设计。其中,Model IO&#…...
【SSH】群晖开启ssh访问
群晖开启ssh访问 假设 你需要设置群晖 账号 test-user 开启ssh访问 设置 你的 test-user 为管理员权限 否则你无法通过cmd 面板 连接访问 群晖你需要哪个账号 就使用哪个账号终端 cmd连接 否则需要考虑后续创建 rsa 公密钥文件的 所属权 问题账号密码连接登录终端 ssh -p 端…...

Vue 移动端(H5)项目怎么实现页面缓存(即列表页面进入详情返回后列表页面缓存且还原页面滚动条位置)keep-alive缓存及清除keep-alive缓存
一、需求 产品要求:Vue移动端项目进入列表页,列表页需要刷新,而从详情页返回列表页,列表页则需要缓存并且还原页面滚动条位置 二、实现思路 1、使用Vue中的keep-alive组件,keep-alive提供了路由缓存功能 2、因为我项…...

【MVCC】深入浅出彻底理解MVCC
MVCC概述 MVCC(Multi-Version Concurrency Control)即多版本并发控制。主要是为了提高数据库的并发性能而提供的,采用了不加锁的方式处理读-写并发冲突,确保了任何时刻的读操作都是非阻塞的。只需要很小的开销,就可以…...

【问题解决】ubuntu安装新版vscode报code-insiders相关错误
问题 目前 vscode官网 最新的包为 insiders_1.89.0-1712297812_amd64.deb ,双击或者使用sudo dpkg -i code-insiders_1.89.0-1712297812_amd64.deb安装后报错,执行其他命令也报错。 安装环境: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,找打设置的图标,在点击设置,或者直接使用快捷键,【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:从前台传递过来的参数不能为null,如果为空,会在控制台日志中把message打印出来 Range:范围,最大多少,最小多少 Patten,标注的字段值必须符合定义的正则表达式(按照业务规则࿰…...

Harmony鸿蒙南向驱动开发-UART接口使用
功能简介 UART指异步收发传输器(Universal Asynchronous Receiver/Transmitter),是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输。 两个UART设备的连接示意图如下,UART与其他模块一…...
【示例】MySQL-事务控制示例:账户转账-savepoint关键字
前言 本文讲述MySQL中的事务,以账户转账为例,体会事务的概念,并讲解事务相关的一个关键字用法: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中的板文件后,想使用I/O设备模型,使用串口3或者串口4收发时,发现串口3或者串口4没反应。出现问题:程序一直跑在 while (__HAL_UART_…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...