基于unity mirror框架下的2D像素弹幕联机游戏的简单功能分享

Mirror可以在Unity商店免费获得

官方文档:

Mirror Networking - MirrorDocs, Guides, FAQ, Templates, Examples, API, and more!https://mirror-networking.gitbook.io/docs/

Mirror入门基础

(在此之前你所需要知道,理论上只要会使用Command,[SyncVar],[SyncVar(hook=nameof(OnHealthChanged))],ClientRpc就可以完成所有的事情,一定要明白,玩家都是发信息给主机,主机判定完后返回给玩家信息,玩家再根据信息执行。)

1.[Command]

客机想出牌时,需要经过主机,这叫发送指令(客机单方面告诉主机)(在你的方法前标注[Command]实现)

2.[ClientRpc]

主机将玩家1打出黑桃A的信息告诉所有人,这叫广播(主机告诉所有客机)(在你的方法前标注[ClientRpc]实现)

3.[SyncVar]

在 Mirror 中,[SyncVar] 用于标识一个变量,这样当其值在服务器上发生变化时,它会自动同步到所有连接的客户端上。例如,你有一个表示玩家健康值的变量。当玩家受到伤害并且其健康值在服务器上发生变化时,你想要这个变化自动反映在所有客户端上。

[SyncVar]

public int health = 100;

此外,[SyncVar] 还有一个叫 hook 的可选属性,它允许你指定一个方法,当变量值发生变化并同步到客户端时,这个方法会被调用。这对于当值变化时需要执行某些操作(例如更新UI)非常有用。

[SyncVar(hook = nameof(OnHealthChanged))]

public int health = 100;

public void OnHealthChanged(int oldHealth, int newHealth)

{
    // 这里可以做一些当健康值变化时的操作
}

4.islocalplayer

  通过islocalplayer来限制非本地客户端操控别的玩家角色,通俗来说你要是不加这一句的话你的输入会操控所有玩家。

介绍项目

在mainscene里写了一个基于network manager的networkroommanagerExt组件

用于玩家房间管理和场景的网络管理器

联机方式

远程联机

运输协议选择的是mirror的kcp(很快速的传输协议,想做mmorpg的用Telepathy Transport,你是做独游的?那当我没说捏),这里我是用的阿里云服务器,配置好端口和ip地址在服务器部署一个服务器平台的项目即可远程联机联机。

(在远程服务器上这样部署就没啥问题)

添加network manager hud可以输入ip地址进行远程链接

SteamP2P远程联机

我没有用p2p,有官方文档可以了解捏这里我就不说了Mirror Networking - Mirror (gitbook.io) 

局域网联机

 配置好传输协议后添加discovery hud即可局域网搜寻ip地址

配置Networkmanager预制体部分

Mirror中,每个玩家必须要有一个自己的控制对象(最差也要给个有Transform的空物体),在Player Prefab中拖入玩家预制体,勾选Auto Create Players时当有玩家加入时,Mirror会为玩家创建预制体然后把控制权交给对方。在Mirror框架下最好使用这个创建的玩家预制体来进行游戏。

Player Spawn Method

如果不进行继承重写,默认的需要配合上方这个组件使用,创建一个空物体,绑定组件,拖拽到你想要生成玩家的位置,选择生成模式,Manager会遍历所有带组件的物体,在他们的位置依次生成。

Registered Spawnable Prefabs

顾名思义,注册玩家以外需要生成的物体比如子弹,事例场景中的球。只要是需要进行网络同步,位置信息,或者其他操作等等,都需要把预制体拖进这个表中。

总结:通过这一组件,玩家客户端可以被相互连接起来,并生成各自的玩家物体来进行游戏。

接下来讲解另一个关键组件

网络唯一标识符,简单理解就是 键值对,这里是NetworkIdentity GamaObject对。物体这么多,主机动了一个物体怎么告诉玩家动了哪个物体,就是读这个组件内的netID来确认那个物体动了。

它的另一个功能就是,可以标记物体的所有者,来确定每个物体的所有者是谁,不是所有者就无法对它进行操作,所以客户端的玩家只能操作自己的角色,因为那个是他的物体,其他都不是。

当物体使用Mirror同步时都需要绑定这个组件,否则无法运行。

同步组件

Transform同步

这个组件绑定在物体上时,物体的Transform会进行同步,我们讲解一部分参数。

控制权,勾上的话,客机也可以对它进行修改,一般不勾。

 

Sync XXX表示是否同步,勾上就同步。

Interpolate XXX表示使用插值,位置同步信息不是每帧的,勾上时可以平滑丢失的帧,让移动更加丝滑。

滚动条是对插值的调整。

目前新版的mirror框架network transform分为两种(reliable和unreliable)

Reliable :

    • 当你需要确保一个消息被成功传输并被对方接收,你应该使用Reliable传输。
    • 这种传输方式可能会重传消息,直到确认消息已被接收或达到重传次数上限。
    • 对于像游戏状态同步、玩家命令或其他重要信息,可靠传输是很有必要的。
    • 但是,这种方式可能会引起延迟,因为系统可能需要等待确认或进行重传。

Unreliable:

    • 当消息的即时传输比其完整性更为重要时,你应该使用Unreliable的传输。
    • 这种方式不保证消息一定会到达,也不保证消息的顺序。
    • 但它可以更快速,因为它不等待确认也不进行重传。
    • 在某些游戏中,比如快节奏的射击游戏,玩家的位置和动作可能会经常更新。在这种情况下,使用不可靠的更新可能是合适的,因为玩家的最新状态比过去的状态更为重要。

来看看一个简单的子弹同步脚本

我的做法是在开火时将子弹的位置和旋转信息告诉给服务器,至于子弹的速度逻辑我让他在本地客户端运行,但是需要使用 [SyncVar(hook = nameof(OnPositionChanged))]来实时同步子弹的位置(宰粽大作战中有一个反弹子弹的武器,如果在游戏中你没有改变子弹位置的因素可以不实时同步位置)

Gun脚本

Bullet脚本

同步动画

使用network animator

勾上client authority 然后来看看一个简单同步动画的例子

客户端调用服务器通知他准备播放开火动画,再通过服务器广播给所有客户端以达成同步动画的功能

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值