unity3d 双人巡逻兵网络游戏

github传送门如下
https://github.com/ddghost/unity3d_n/tree/%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F

这次作业要做的是一个网络游戏,我不想重做一个新的游戏,感觉以前做过的游戏中巡逻兵会有意思些,所以我选择了做一个双人巡逻兵。由于开始不熟悉网络游戏客户端和主机是如何交互同步的,其实做完了这次作业也还是有些不懂的地方,所以代码有的地方会冗余,还有的地方实现起来很丑陋。

这个是开始的效果,刚开始开主机在中间的房子只有一个玩家,在另一个客户端连上主机后,出现了两个玩家(只能两个人玩,一个主机,一个客户端,而且客户端不能在连上后断开再连,否则会有奇葩的效果,等下会说明为什么)。

这个就是玩起来的效果,由于我是单人控制,因此只能分开玩,先玩左边,再玩右边,人物都死了之后,主机玩家可以选择重新开始。

由于本次是在之前的代码基础上改,所以关于巡逻兵游戏的代码细节就不再详述,只讲几个关键的问题和步骤。

准备工作

开始的时候我还是一脸懵逼的做,那就先从抄开始,首先抄课上老师给的步骤。先按ctrl+s场景保存,然后在左上方菜单栏选file->build setting。

然后添加场景,不然添加场景到networkManager会有问题。

然后给所有预置添加netWorkIndentity和networkTransform(一些静态对象也许不用加network transform),并且network transform的第一个属性send rate设置为25(高点的话,客户端就不会有卡顿的效果)。

player的netWorkIndentity选择local player authority,并且network transfrom的第二个属性不要选rigidbody 3d,选transform(选rigidbody的话人物被撞倒后重新开始,人物还是倒下的,原理的话不太清楚),同时还要加network animation组件来同步动画,老实说,不明白这些为什么也要手动加,开始搞了半天不知道为什么动画不同步,这些东西都要手动加真的挺麻烦,就不能全都自动同步吗?

然后创建一个空对象,命名为NetworkManager,并且添加NetworkManager和NetworkManager Hud组件。注意networkManager组件要改的有如图四个红圈,第一个红圈设置场景,如果刚才build setting没弄好是设置不了的。第二个红圈设置玩家预置,第三个设置玩家初始位置为round bin,第四个设置孵化的预置(把要用到的预置加进去好了,懒得想)。

为了有两个初始位置,添加两个空对象p1,p2,添加network start position组件,这样在network manager中玩家初始位置选择了round bin的情况下,每次玩家加入,玩家的位置都会在这两个位置轮流选,这也是为什么不能连了再重进,那样第三次进入的位置就会是第一次进入的位置,这样玩家就会重叠在一次,显然不行。

然后这个时候点菜单来的file->built&run,这会弹一个游戏框,游戏启动可以设置窗口化和分辨率,然后unity也点击运行,这样运行两个游戏,一个当主机,一个连上去,就可以看到两个倒霉的玩家出现在屏幕中,并且因为设置了刚体,有重力,所以一直往下掉。

加载场景

做到这里,麻烦才开始来了。首先第一个问题就是以前是使用场记加载场景的,但这次作业是网络游戏,那么场景该怎么加载呢?首先搞明白场记放哪里,场记应该要放在服务器那里,因为它应该是惟一的,不能放在客户端那里。那么我们和以前一样就在场景中先弄个空对象,命名为main,由于是网络游戏,这个main要添加networkIdentity组件,勾选server only,然后把场记脚本挂上。

同时注意到所有预置都是场记加载的,为了在客户端也显示,就要把它孵化出来,因此每个加载预置的语句下面都加上NetworkServer.Spawn(····)

    public void loadResources(){var map = (GameObject)Instantiate (Resources.Load ("Prefabs/map"), Vector3.zero, Quaternion.identity);NetworkServer.Spawn(map) /////!!!!!!!!checkerCtrl = new CheckerController[checkerLoc.Length];playerCtrlList = new List<PlayerController> ();for (int loop = 0 ; loop < checkerLoc.Length ; loop++) {GameObject checker = (GameObject)Instantiate (Resources.Load ("Prefabs/checker"), checkerLoc[loop] , Quaternion.identity) as GameObject;NetworkServer.Spawn(checker);  /////!!!!!!!!checker.name = "checker" + loop.ToString ();checkerCtrl[loop] = checker.AddComponent(typeof (CheckerController)) as CheckerController;}}

这样应该就能加载出场景(由于做的时候很混乱bug多,不确定有没有漏步骤)。

客户端的玩家操作

场景好了,接下来就是控制还有游戏的逻辑问题。首先是玩家的控制问题,要判定控制的是不是本地玩家,不然连别的玩家都能控制那就大错特错了。代码可参见如下,isLocalPlayer能判断控制的到底是不是本地玩家。

    void Update () {if (!isLocalPlayer)return;moveControl ();}

除此之外,注意到游戏结束后重新开始,要重新设置玩家的位置,动画等等,这些是要每个客户端都做的,因此函数前要加[ClientRpc]。如果不这样的话,各个客户端就不同步了。

    [ClientRpc]public void RpcResetPosition(Vector3 position){gameObject.GetComponent<Rigidbody> ().velocity = Vector3.zero;this.transform.rotation = Quaternion.identity;this.transform.position = position;ifRun = false;nowDirection = 0;status = true;}[ClientRpc]public void RpcSetAnimatorBool(string name , bool boolValue){if (isLocalPlayer)this.GetComponent<Animator> ().SetBool (name, boolValue);}

主机的场记

其次就是场记的逻辑,由于玩家是在场记脚本初始化后分开加入的,而场记要判断玩家是不是都死了才能决定游戏是否结束,因此场记要有一个队列存储玩家。玩家刚进入游戏的时候就要通知场记把玩家加入到这个队列中。通知场记的函数CmdAddPlayerToScene是要在主机而不是客户端上执行的,因为只有主机上才有场记,因此要在该函数上写 [Command]。
同时注意到,主机玩家创建游戏后,第二个玩家加入时,主机上会新加入第二个玩家控制的player,上面也有挂载player上的脚本,所以CmdAddPlayerToScene会在主机上的player调用一次,客户端上的player也调用一次,这样第二个玩家加入,仅一个玩家加入,场记却要加入两个玩家入队列,这是不对的,因此通知场记时要注意是否是本地玩家加入。

    void Start () {if(isLocalPlayer)CmdAddPlayerToScene();status = true;}[Command]void CmdAddPlayerToScene(){Director.getInstance ().CurrentSceneController.addPlayer (gameObject);}

最后,同时也是我比较头疼的地方,那就是游戏结束后,代表得分的红色小块要全部重新显现出来,正常来说直接setActive就好了,但是这里像以前那样只在场记set一下是不行的,因为只有主机有场记,所以只有主机玩家的红色块才会重新,会主机玩家然后我又试着在场记新弄了一个函数,前面加个[ClientRpc],希望每个客户端都会这样去做,结果报错。最后我就在场记调用主机玩家的一个[ClientRpc]的函数,这样就可以了,感觉很迷,难道是因为客户端中没有场记那个函数,所以场记的函数不能在所有客户端调用?最后我采取的这种方案感觉不是个好的方法。

    [ClientRpc] //player控制脚本public void RpcSetScore(GameObject score , bool boolValue){score.SetActive (boolValue);}//场记代码for (int loop1 = 0 ; loop1 < checkerLoc.Length ; loop1++) {checkerCtrl [loop1].reset ();playerCtrlList [0].playerScript.RpcSetScore (checkerCtrl [loop1].getScore() , true );//!!!!}

结语

最后不得不说,网络游戏的同步还是个很头痛的东西,第一次设计感觉还是没有什么章法,代码写的有些乱,可能还有一些小bug,刚开始觉得只要把以前的代码改改就好了,结果这次作业还是做了很久。边写博客边发现代码冗余,又边改代码,感觉写博客还是能反思不少,发现不少问题。

unity3d 双人巡逻兵网络游戏相关推荐

  1. Unity3D制作巡逻兵小游戏

    一.主体代码架构说明 二.发布与订阅模式 相关类图 C#中的实现:delegate委托类型和event事件机制 意义 在本次游戏中的具体应用 三.游戏主要行为分析 1. 巡逻兵的行为 与其他物体/角色 ...

  2. 用Unity3D实现智能巡逻兵游戏

    用Unity3D实现智能巡逻兵游戏 项目地址 智能巡逻兵游戏 完成效果图 类图 要求 游戏设计要求: 创建一个地图和若干巡逻兵(使用动画): 每个巡逻兵走一个3~5个边的凸多边型,位置数据是相对地址. ...

  3. Unity3D 从入门到放弃 ——巡逻兵 观察者模式

    Unity3D 从入门到放弃 --巡逻兵 作业需求 游戏规则: 创建一个地图和若干巡逻兵: 每个巡逻兵走一个3~5个边的凸多边型,位置数据是相对地址.即每次确定下一个目标位置,用自己当前位置为原点计算 ...

  4. 基于Unity3D开发的智能巡逻兵小游戏

    智能巡逻兵小游戏 作业要求 游戏设计要求:智能巡逻兵 创建一个地图和若干巡逻兵(使用动画): 每个巡逻兵走一个3~5个边的凸多边型,位置数据是相对地址.即每次确定下一个目标位置,用自己当前位置为原点计 ...

  5. 3D游戏设计-智能巡逻兵

    游戏简介 躲过巡逻兵的追杀. 游戏规则 一共有九个房间,每个房间有一个巡逻兵,玩家进入房间时该房间的巡逻兵会追杀玩家. 玩家从一个房间进入另一个房间(躲过追杀)时加一分. 玩家被巡逻兵追上则死亡,游戏 ...

  6. unity实现简单巡逻兵

    unity实现简单巡逻兵 游戏视频 游戏要求 创建一个地图和若干巡逻兵(使用动画): 每个巡逻兵走一个3~5个边的凸多边型,位置数据是相对地址.即每次确定下一个目标位置,用自己当前位置为原点计算: 巡 ...

  7. Unity巡逻兵游戏-与怪兽战斗!

    Unity巡逻兵游戏-与怪兽战斗! 本次作业项目地址: https://github.com/StarashZero/3DGameDesign/tree/master/hw7 游戏简介 操作迷路少女与 ...

  8. 模型与动画——智能巡逻兵

    文章目录 模型与动画--智能巡逻兵 一.提交要求: 二.具体玩法: 三.订阅发布模式MVC框架: 四.程序实现: 4.1 玩家部分实现: 4.1.0 玩家预制和动画设置: 4.1.1 Interfac ...

  9. 3D游戏作业7:巡逻兵

    3D游戏作业7:巡逻兵 思路 本次作业还是采用MVC结构进行设计.不同的是,这次作业引用了一些动画.需要自定义Animator Controller以及相应的算法. 另外,为了使运动看上去更加&quo ...

  10. unity项目——德军总部(巡逻兵)

    先放Github地址:https://github.com/kotomineshiki/SearchArmy 视频地址:https://www.bilibili.com/video/av2332653 ...

最新文章

  1. 推荐一个你最喜欢的辅助办公软件,你会推荐什么?
  2. [训练日志] 7月22-31日
  3. OpenCV蒙版图像make mask image的实例(附完整代码)
  4. vue2中的过滤器filter怎样实现首字母大写
  5. linux系统下安装jdk教程
  6. 学习生信的系列教程 | 留言您是如何学习生信的免费获取北大出版《Python数据分析》书籍...
  7. (三)用于构建AI语言翻译系统的工具
  8. 阶乘末尾连续零的个数
  9. 【报告分享】2020年中国5G经济报告--助力新时代高质量发展.pdf(附下载链接)...
  10. Android应用程序的Activity启动过程简要介绍和学习计划 .
  11. nvarchar和varchar的区别
  12. Hershell:跨平台反向Shell生成器
  13. 现代信号处理功率谱估计MATLAB,基于Matlab实现现代功率谱估计
  14. 聚类分析与SPSS实现——《社会统计分析方法》
  15. 基于单片机的心率监测系统设计(#0403)
  16. 5miles:这家电商公司,想做推动区块链技术落地的标杆
  17. java js css 压缩工具_JSCSS压缩工具YUICompressor
  18. TZOJ 3244 Happy YuYu's Birthday(数学几何)
  19. 诡辩六论——微信陌陌如何话题不断的聊天
  20. [渝粤教育] 中国地质大学 计算机会计理论与实务 复习题

热门文章

  1. java通用排序工具类
  2. Layabox 实现 PageView 翻页
  3. 常见的技术文档英文单词
  4. 复杂网络python中心度指标算法学习(画图、计算)
  5. 办公用品管理系统服务器版,恒达办公用品管理系统
  6. 实现网页长截图的常见思路总结
  7. 工具说明书 - 滚动截屏和录屏软件ShareX
  8. 神经网络训练的一些方法
  9. 【GPT2】Language Models are Unsupervised Multitask Learners
  10. 国美在线php面试题,国美电器面试经验