UNet实例:Uno
发表于2017-01-29
前言
和同事经常在吃饭的时候玩几盘uno桌游,有些餐厅拒绝玩纸牌,我希望放在手机里随时能玩。
我觉得unet搞demo非常的方便,客户端/服务端代码通用,调试方便,想经过几个小项目来深入理解UNet。
和同事经常在吃饭的时候玩几盘uno桌游,有些餐厅拒绝玩纸牌,我希望放在手机里随时能玩。
我觉得unet搞demo非常的方便,客户端/服务端代码通用,调试方便,想经过几个小项目来深入理解UNet。
需求
第一版要求实现功能
Uno基本版规则
2-9人联机,先输出android版
UI设计
主界面
玩家头像框
卡牌框
规则说明
胜负规则:最先出完手牌获胜,并计算每人的手牌分数,普通牌0-9分,功能牌20分,万能牌50分
出牌时间:每回合60s,超时罚1张
代码组织结构
具体逻辑代码不贴了,有兴趣见gitHub: https://github.com/vbetter/Uno/
简单介绍下我们DEMO需要掌握的知识点,详见https://docs.unity3d.com/Manual/UNetConcepts.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | //继承NetworkBehaviour 基础数值型、Vector3、Struct //同步变量 [SyncVar(hook = "SyncRound" )] public int Round = 0; //回合数 //同步变量,当Round被改变时,同步给所有客户端 void SyncRound( int value) { Round = value; //刷新UI MyUIMain.SetRound(value); } //同步列表 SyncListString SyncListFloat SyncListInt SyncListUInt SyncListBool [System.Serializable] public struct CardStruct { public int UID; //卡片唯一id } public class SyncListCardItem : SyncListStruct { } SyncListCardItem m_myCards = new SyncListCardItem(); void CardStructChanged(Operation op, int itemIndex) { Debug.Log( "changed:" + op); } void Start() { m_myCards.Callback = CardStructChanged; } [Server] //只在服务端运行的代码 void InitWithServer() { } [Client] //只在客户端运行的代码 void InitWithClient() { } [ClientRpc] //服务端调用所有客户端函数,函数名必须Rpc开头 void Rpc_UpdateLastCard(CardStruct card) { LastCard = card; } [Command] //客户端调用服务端函数,函数名必须Cmd开头 public void CmdGetCards( uint numb) { NetworkGameMgr.Instance.ServerGetCards( this ,numb); } |
介绍下Unity5.0的Unet
RPC是什么? RemoteProcedureCall 远程过程调用协议,最大特点就是Client和server能像调用函数一样进行通讯。
LocalClient:一种特殊的客户端,服务器和客户端可以在同一个设备上
RemoteClients:远程客户端
它们的区别是LocalClient和Server在同一个进程里,可以通过消息队列直接通讯,而RemoteClient要通过网络连接通讯
Unity希望通过LocalClient和RemoteClient代码相同的特点来提高开发效率

如果要创建和生成一个网络对象,可以使用NetworkServer.Spawn(obj);但是必须由服务器调用,会同步给所有的客户端。
一个客户端不能直接调用另一个客户端,必须使用common命令调用服务端,在使用ClientRpc调用客户端函数
可以用isLocalPlayer来判断客户端是否是你自己,并且拥有本地控制权限(hasAuthority属性判断权限),例如你可以控制自己的角色移动,但不能控制其他玩家的角色。

NetworkIdentity
网络身份标识组件,网络对象必备,由服务器通过NetworkServer.Spawn来生成
可以在NetworkInformation面板里面看到该网络对象的属性
ServerOnly:如果勾选,对象就不会在客户端上被创建。
LocalPlayerAuthority:本地权限,表示该对象能被玩家操作,可调用common命令调用服务端函数

NetworkBehaviour,文档https://docs.unity3d.com/Manual/class-NetworkBehaviour.html
它是网络对象组件,一般和NetworkIdentity一起使用,继承后能使用HLAPI,例如Common、ClientRpc、SyncVar、SynEvent
下图为本地权限的客户端和服务端通讯。
