由于mirror的概念和API同已经弃用的unet很相似。同时mirror的文档在基础概念比较少,而且全英文。所以可以先从unet的官方文档开始入门。UNet

mirror入门

1) 运行环境:
从AssetStore下载mirror插件。
注意.net版本要求。需要在playersetting1里将.net版本改成.net4.x。

2) 构建NetworkManager
建立一个空物体,将networkManager,Transport,networkManagerHUD组件挂在上面。

3) 制作playerPrefab
建立一个cube,在上面挂上networkIdentity作为在网络同步的唯一标识。之后加上networkTransform做位置的网络同步。勾选Client Authority,说明是客户端控制位移(因为是玩家)。在挂上一个随机移动的mono脚本。打包运行后发现server端上有跳跃的现象。


是因为server上物体随机位置计算了一次后,又同步了client上的位置一次造成闪烁。于是为了解决这个问题,就需要将脚本从继承MonoBehaviour改为继承NetworkBehaviour。

Start函数 ——>重写OnStartLocalPlayer函数(视脚本所挂物体而定(这个是只在客户端运行的函数)详看networkBehaviour的必然函数执行顺序)
还是要避免直接使用mono的start来初始化。因为在host下,mono的start只执行一次。但host在内部分为localclient和server。虽然共享场景,但依然可能导致其中一个没有被初始化(执行顺序不一定)。

4) client向server发送命令(command)
要将命令封装为一个方法,方法名以Cmd开头,给方法添加[Command]特性即可。

 [Command]private void CmdSetRandomColor(){Debug.Log("CMD");Color rc = Random.ColorHSV();SetColor(rc);RpcSetRandomColor(rc);}

注意:1.实际上是client调用了server上的方法,显然command不能从server上发出。2.要在调用command方法时应判断是不是localPlayer,否则player即使不是本地玩家会也去调用command方法,导致弹出警告(command也不会执行,因为一个玩家不能在另一个玩家的游戏对象上调用命令,只能在自己的游戏对象上调用命令)。
由于是client——>server,会发现虽然server上的颜色改了,但client上并没有变化。

5) 于是需要一个server的回调,server——>client。
类似command用法,用一个方法封装回调。方法名以Rpc开头,添加[ClientRPC]特性即可。

[Command]private void CmdSetRandomColor(){Debug.Log("CMD");Color rc = Random.ColorHSV();SetColor(rc);RpcSetRandomColor(rc);}[ClientRpc]private void RpcSetRandomColor(Color color){SetColor(color);}

于是client就能和server同步。

client—调用—>server的[command]方法—调用—>client的[ClientRPC]方法
clientRpc是会向所有client回调这个方法,有时候我们想让特定的client接受特定的回调。
于是就有了回调特定client的方法。同[clientRpc]类似。方法名以Target开头,添加[TargetRPC]特性,要注意的是该方法至少有一个NetworkConnection的形参,用来确定是回调哪一个client。

 [Command]private void CmdSetRandomColor(){Debug.Log("CMD");Color rc = Random.ColorHSV();SetColor(rc);var nid = GetComponent<NetworkIdentity>();TargetSetRandomColor(nid.connectionToClient,rc);}[TargetRpc]private void TargetSetRandomColor(NetworkConnection con, Color color){Debug.Log("target");SetColor(color);}

6) 值同步:SyncVal
如果想同步脚本中某一个值的话,可以给值添加[SyncVar]特性。

[SyncVar]private Color _color;

在Inspector面板上就会出现同步模式

默认广播给所有client,同步间隔0.1s
还可以指定值更新的时候,自动调用某个客户端上的方法。

[SyncVar(hook =nameof(SetColor))]private Color _color;
private void SetColor(Color oldColor, Color newColor){var sr = GetComponent<SpriteRenderer>();sr.color = newColor;}

注意:1.调用的方法要有先前值和更新值两个形参。2.host下,所有object都中回调函数都会被调用,要用HasAuthority来限制。(因为host既是server又是client)

7) Object权限详解
在网络中权限是一个很重要的概念。拥有了一个物体的权限就表示有修改该物体的能力。在mirror框架中,server拥有绝大部分联网物体的权限,除了玩家角色和一些特定的物体。拥有了权限的玩家客户端就可以通过commands来同server交互,改变已有权限的物体。
获得权限的方式:
1) 玩家预制体在生成是自动赋予了对应的客户端权限。
2) 玩家可以用command用预制体生成object时可以设置该物体的权限。
如下:

[SerializeField]private GameObject _objPrefab;bool check = true;private void Update(){if (check && base.hasAuthority){CmdSpawn();check = false;}    }[Command]private void CmdSpawn(){var obj = Instantiate(_objPrefab);//预制体要先实例化NetworkServer.Spawn(obj, GetComponent<NetworkIdentity>().connectionToClient);}

3) 改变已有的物体的权限。

if (!hasAuthority) return;if (!Input.GetKeyDown(KeyCode.Mouse0)) return;RaycastHit hit;if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100)){NetworkIdentity id = hit.collider.GetComponent<NetworkIdentity>();if (id != null && id.hasAuthority){CmdRequestAuthority(id);  }}}[Command]private void CmdRequestAuthority(NetworkIdentity otherId){otherId.AssignClientAuthority(base.connectionToClient);//将该id的物体权限转到该客户端下}

注意:1)一旦客户端掉线,客户端所拥有的所有物体都会被销毁。
2)networkBehaviour中的localplayer和 hasAuthority 。localplayer是判断当前脚本是不是在当前客户端的玩家角色上 。hasAuthority判断当前客户端是不是有权限控制这个物体。

8) 如何传递基本类型数据
在之前的client和server之间的交互(如command,clientRpc等)可以传递参数的。大部分基本类型如int,float等可以直接发送,部分mirror和unity类型也可以直接传输。如transform,vector3,netidentiy,GameObject等。注意Gameobject需要带有NetworkIdentity组件。可以通过Networkwriter类来确认那些类型被默认支持。
9) 如何传递自定义类型数据
对于没有支持的类型,可以通过自定义序列化器来支持。如下:

public class Item
{public string Name;
}
public class Armour : Item
{public int Protection;public int weight;
}
public class Potion : Item
{public int Health;
}/// <summary>
/// item序列化器
/// </summary>
public static class ItemSerializer
{private const byte ITEM_ID = 0;private const byte POTION_ID = 1;private const byte ARMOUR_ID = 2;public static void WriteItem(this NetworkWriter writer, Item item){if (item is Potion potion){writer.WriteByte(POTION_ID);writer.WriteString(potion.Name);writer.WritePackedInt32(potion.Health);}if (item is Armour armour){writer.WriteByte(ARMOUR_ID);writer.WriteString(armour.Name);writer.WritePackedInt32(armour.Protection);writer.WritePackedInt32(armour.weight);}else{writer.WriteByte(ITEM_ID);writer.WriteString(item.Name);}}public static Item ReadItem(this NetworkReader reader){byte id = reader.ReadByte();switch (id){case POTION_ID:return new Potion{Name = reader.ReadString(),Health = reader.ReadPackedInt32()};case ARMOUR_ID:return new Armour{Name = reader.ReadString(),Protection = reader.ReadPackedInt32(),weight = reader.ReadPackedInt32()};case ITEM_ID:return new Item{Name = reader.ReadString()};default:throw new Exception($"Unknown ItemType :{id}");}}
}

10) NetworkBehaviour的StartCycle
Awake() 最先无论client还是server。
OnstartServer() 仅在server上执行
OnstartAuthority() 仅在client执行,当物体生产时,同时在该客户端有权限时执行
OnStartClient()仅在client执行,用来初始化客户端
OnStartLocalPlayer()仅在client执行,当脚本所在物体为玩家角色时调用,用来设置跟踪相机等
OnStopAuthority()仅在client执行,当客户端失去该物体权限时调用
Start() 顺序不定,通常在最后但不保证每次都是,所以不建议将网络数据放这里处理。

unity Mirror使用笔记相关推荐

  1. Unity Shader 学习笔记(33) 全局光照(GI)、反射探针、线性空间和伽马空间、高动态范围(HDR)

    Unity Shader 学习笔记(33) 全局光照(GI).反射探针.线性空间和伽马空间.高动态范围(HDR) 参考书籍:<Unity Shader 入门精要> [<Real-Ti ...

  2. 【Unity ASE学习笔记】

    Unity ASE学习笔记 一.工具比较 二.ASE插件工具下载 三.ASE界面 主要工作区详解 四.节点 常用节点概览 4.1.贴图节点 4.2.常数节点 4.3.四则运算(+ - * /) 4.4 ...

  3. Unity学习shader笔记[一百]简单焦散Caustic效果

    焦散是模仿光透过水底的一个投影景象 有两个版本,改版最后效果如下 这里是简单的基于物体的焦散,基于水体的焦散思路是水面物体的shader中拿到ColorBuffer,然后用水体的屏幕空间坐标取采集Co ...

  4. 大爱 unity 数字孪生 老卵了 Unity 数字孪生笔记1 工具介绍

    Unity 数字孪生笔记1 工具介绍 火锅肥牛 2020-05-16 20:19:10   106   收藏 1 展开 前言 工欲善其事必先利其器 流程思考 数字孪生本质上一种基于实际物理数据的可视化 ...

  5. Unity DOTS 学习笔记1 - ECS 0.50介绍和安装

    Unity DOTS 学习笔记1 - ECS 0.50介绍和安装 为什么学习这个技术 ECS的全称为Entity Component System,是最早由暴雪在GDC2017上提出的一个新的游戏设计 ...

  6. Unity 2D 学习笔记:游戏实例Sunnyland

    Unity 2D 学习笔记:游戏实例Sunnyland 01安装软件&导入素材 02编辑素材&Tilemap 03图层layer&角色建立 04角色移动 05角色方向& ...

  7. Unity+C#开发笔记(六)| unity中单例模式的使用 | ╭(●`∀´●)╯╰(●’◡’●)╮

    首先单例模式是做什么用的呢?对于我一个萌新来说,目前我用到的就是方便别的类调用!,所以在不继承MonoBehavior的类,我都喜欢加个单例模式方便调用(我知道好像正确原因不是这个0.0但主要是妹看懂 ...

  8. Unity+Mirror实现虚拟现实下的多人连接

    实现虚拟现实环境中的多人连接顾名思义分为两步,首先通过Mirror插件实现3D空间下的多人连接基础功能,其后调整虚拟现实相关内容,最后添加虚拟化身并进行匹配.本篇文章也将从以下三个方面依次完成(使用设 ...

  9. Unity 游戏黑暗之光笔记第一章 完善场景

    Unity 游戏黑暗之光笔记 第一章 完善场景 1. 导入资地形.地貌资源,新建场景,导入地形.地貌prefab 2. 设置相机与视野匹配 选中主摄像机,点选菜单栏中GameObject > A ...

最新文章

  1. ttf,woff2字体转化为png图片,python读取图片
  2. Spring 3.1 事务配置
  3. 图灵九月书讯 ——金秋时节推荐给程序员们的书
  4. 如何在iOS或macOS上检查活动的Internet连接?
  5. mongoose框架示例代码解析(一)
  6. Leetcode--210.课程表Ⅱ
  7. 2021儋州市民族中学高考成绩查询,海南2021高考成绩排名查询,海南高考个人成绩排名如何查询...
  8. 2017.4.20 火星人 思考记录
  9. 下血本了!京东宣布未来三年向湖北投资,助力经济恢复
  10. matlab读取excel第一列,读取excel中的数据把第一列相同的所有行数据输出成一个excel...
  11. 多目标决策---多目标线性规划的解法
  12. Java多线程高并发编程中点点理解
  13. mysql二进制包安装mysql_基于linux使用mysql二进制包安装mysql
  14. lvds输入悬空_LVDS的接口电路设计
  15. 创新创业基础-李德平章节测试答案
  16. 谈谈优化JDBC数据库编程(转)
  17. 0.Dagger2.38.1源码解析-多种类型查询总结
  18. 视频剪辑制作教学:分享十种剪辑技巧,打好基础很重要
  19. MATLAB常用数据导入
  20. 什么是生命?演讲原稿

热门文章

  1. postgreSQL源码分析——索引的建立与使用——GIN索引(3)
  2. 黑盒法测试c语言,黑盒测试的测试用例设计方法(经典理论知识,推荐)
  3. 计算机教学assure模型教案,ASSURE模型在大学计算机基础教学中的应用探索
  4. mysql分页总页数算法解析_详解MySQL的limit用法和分页查询语句的性能分析
  5. 手机支付优惠促销活动插画素材,拿来就能用,高效省时。
  6. 干货分享|UI设计可临摹编辑的线框素材,还会觉得交互原型画得丑?
  7. UI设计素材干货模板|手机app夜间模式相关素材
  8. UI实用干货素材|工作管理、日程日历专辑
  9. python 判断线程状态_Python 线程和进程
  10. C++设计模式详解之装饰者模式解析