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

2024-04-13 13:52

本文主要是介绍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)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/900317

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份