unity多人联机(Mirror插件)有史以来最全的基础教程(附加报错提示和官方手册修改)
目录
START👀
(☞゚ヮ゚)☞Mirror简介☜(゚ヮ゚☜)
组件介绍:
组件1:NetworkManager
组件2:NetworkManagerHUD(需要配合Network Manager组件)
组件3:NetworkIdentity
组件4:network discovery&network discoveryHUD
错误注意:
最后,对手册内容的一点修改:
今天我们只讲代码和组件,大家拿小本本记好了,字数比较多,大家不妨点个关注?
START👀
谁不想简单的用unity做一个好玩的多人游戏呢ヾ(•ω•`)o?但unet已经network类写代码又太麻烦,
用photon插件又不习惯,这时,Mirror插件降临了……
(☞゚ヮ゚)☞Mirror简介☜(゚ヮ゚☜)
Mirror是unity store里的一个插件,当然下载地址大家自己去找吧!嗯。。。看在你们那么诚恳要求我,那就:Mirror | 网络 | Unity Asset Store
那可能有人问了,有那么多多人联机插件,那为什么非要选mirror呢?嗯。。那是因为mirror插件更符合unet老手(dalao)的习惯, 他与unet极其相似,可以说是没有区别,而且他是unet的bug修复版,连接更稳定。相比之下photon就不是很习惯(不是贬低photon),瞧,格局不就打开了?
Mirror对unet:“哥哥,哥哥~我和你那么想,你好朋友photon不会生气的吧~(●ˇ∀ˇ●)
组件介绍: 组件1:NetworkManager
这个组件研究过unet的应该都知道,但为了新手着想,我们详细介绍一下。啊,我真是太仁慈了!
第一个Configuration栏和第三个network Iofo我们都默认,基本是没必要改动的(要改最好也在代码里改),offline和online是离线界面和游戏界面,
比如说我们新建一个offline场景,在里面放一个network manager的network managerHUD(等会会讲),然后再新建一个online场景,把他们都注册到build setting(生成设置)里的build里的场景栏中(拖进去),offline在上。然后我们进入offline场景,运行,点击host,便会进入online(在线场景)。
———————————————–分割线——————————————————-
player Object栏:
玩家预制件(Player Prefab):这个不需要解释吧。
自动创建播放器(Auto Create Player):默认勾选,勾选的话当连接服务器时会自动生成上面的“玩家预制件”。
玩家生成方法(Player Spawn Method):如果要做一个合理的多人游戏,就要有若干个出生点,我们再场景中新建一个空物体,然后在他身上挂载一个network start position组件,他的坐标就是我们的出生点啦,当然我们可以把它复制粘贴若干个出生点。这个时候,如果玩家生成方法为”随机“(Radom),那么就会在几个出生点之间随机选择一个点生成玩家预制件,如果选择轮循机制,那么就会按顺序在每个点生成玩家。
最下面有个列表(Registered Spawnable Prefab),他是用来放游戏中需要孵化的物体的,比如说enemy(敌人),bullet(子弹)啊,都给它拖进去,这里给大家看一下发射子弹的代码:
using UnityEngine;using Mirror;public class Playercode : NetworkBehaviour { public GameObject bullutprefab;//子弹预制件 [Command]//客户端同步 void CmdFire()//函数名要以Cmd开头,注意大小写 { GameObject bullut = Instantiate(bullutprefab, transform.position, this.cam.transform.rotation);//生成子弹 bullut.transform.Translate(1, 0, 0);//防止子弹撞到角色 GameObject.Destroy(bullut, 2.0f);//两秒后删除 bullut.GetComponent().velocity = this.cam.transform.forward * 40;//施加力 NetworkServer.Spawn(bullut);//服务器孵化,同步客户端 }} 组件2:NetworkManagerHUD(需要配合Network Manager组件)
他会自动绘制一个GUI:
Host(主机):相当于又是服务器又是客户端。
Client:连接服务端,后面是服务端IP地址,localhost为本地端口,相当于自己连接自己。
Server Only:只当服务端。
但是,这个UI界面不(Guo)太(Yu)好(Chou)看(Lou),所以我们一般不用这个组件,都会自己制作GUI。
组件3:NetworkIdentity
一般游戏内除了包含network manager组件的物体都要挂在此组件,包括即将孵化的。这玩意儿只有俩选项,一个勾选框Server Only,意思是只有服务端能操作,大家根据自己的需要勾选。第二个是visible,里面有三个选项:默认(Default)、强制隐藏(Force Hidden)、强制显示(ForceShown),个人感觉没啥用,大家默认就行。
组件4:network discovery&network discoveryHUD
这个network discovery组件也需要配合network manager使用,他可以列出局域网内所有的服务器,其中有个transport栏,我们需要把与network manager组件在一起的Kcp transport组件拖进去,不然无法运行。
network discoveryHUD,与networkmanagerHUD差不多,唯独少了一个Client,多了一个find server
作用是点击find server就会 把局域网内的所有比赛(服务器)列出来,但仅限局域网。
更多进阶用法:Network Discovery – Mirror (gitbook.io)
手册里啥都有。
错误注意:
1,场景内所有挂在了你的代码的物体都会默认添加network identity,但network manager组件与network identity组件放在一个物体上会报错
2.如果物体内有network manager组件但是没有Kcp transport组件,会报错。
3.如果场景内有多个network manager组件,会报错。
4.如果角色预制体托不进player prefab栏,可能是没有挂在network identity组件。
5.角色代码必须有if (!isLocalPlayer) return;否则。。。后果自己知道。
最后,对手册内容的一点修改:
如果我们想在进入游戏前设置好player的各种信息,比如说name,那么我们得自己编一个network manager。
using Mirror;using UnityEngine;using UnityEngine.UI;public class createplayer : NetworkManager//继承network manager类{ public InputField myname; public override void OnStartServer() { base.OnStartServer(); NetworkServer.RegisterHandler(OnCreateCharacter); } public struct CreateMMOCharacterMessage : NetworkMessage { public string playername; } public override void OnClientConnect() { base.OnClientConnect(); // 你可以在这里发送消息,或者你想要的任何其他地方 CreateMMOCharacterMessage characterMessage = new CreateMMOCharacterMessage { playername = myname.text }; NetworkClient.Send(characterMessage); } void OnCreateCharacter(NetworkConnectionToClient//官方手册里会报错,要改成这样 conn, CreateMMOCharacterMessage message) { // PlayerPrefab是在Network Manager的 inspector 中指定的, // 但您可以在每个比赛中使用不同的预制件,例如 GameObject gameobject = Instantiate(playerPrefab); // 应用消息中的数据,但要适合您的游戏。 //这里的playercode是作者游戏里player的主代码 Playercode player = gameobject.GetComponent(); player.playername = message.playername;//playername是作者在自己代码里定义的 // 调用它以将此游戏对象用作主控制器 NetworkServer.AddPlayerForConnection(conn, gameobject); }}
今天就这样了,肝了四千多字,后面我还会出更多教程,如果我的博文有地方要修改或者你还有什么疑问可以私信我。
end..